<!DOCTYPE html>
<html lang="en-us">
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    
<meta charset="UTF-8">
<title>Request Body Search | Elasticsearch Guide [7.7] | Elastic</title>
<link rel="home" href="index.html" title="Elasticsearch Guide [7.7]">
<link rel="up" href="search.html" title="Search APIs">
<link rel="prev" href="search-search.html" title="Search API">
<link rel="next" href="async-search.html" title="Async search">
<meta name="DC.type" content="Learn/Docs/Elasticsearch/Reference/7.7">
<meta name="DC.subject" content="Elasticsearch">
<meta name="DC.identifier" content="7.7">
<meta name="robots" content="noindex,nofollow">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://cdn.optimizely.com/js/18132920325.js"></script>
    <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
    <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
    <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
    <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
    <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
    <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
    <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
    <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
    <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
    <link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192">
    <link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
    <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
    <link rel="manifest" href="/manifest.json">
    <meta name="apple-mobile-web-app-title" content="Elastic">
    <meta name="application-name" content="Elastic">
    <meta name="msapplication-TileColor" content="#ffffff">
    <meta name="msapplication-TileImage" content="/mstile-144x144.png">
    <meta name="theme-color" content="#ffffff">
    <meta name="naver-site-verification" content="936882c1853b701b3cef3721758d80535413dbfd">
    <meta name="yandex-verification" content="d8a47e95d0972434">
    <meta name="localized" content="true">
    <meta name="st:robots" content="follow,index">
    <meta property="og:image" content="https://www.elastic.co/static/images/elastic-logo-200.png">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
    <link rel="icon" href="/favicon.ico" type="image/x-icon">
    <link rel="apple-touch-icon-precomposed" sizes="64x64" href="/favicon_64x64_16bit.png">
    <link rel="apple-touch-icon-precomposed" sizes="32x32" href="/favicon_32x32.png">
    <link rel="apple-touch-icon-precomposed" sizes="16x16" href="/favicon_16x16.png">
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <link rel="stylesheet" type="text/css" href="/guide/static/styles.css">
  </head>

  <!--© 2015-2021 Elasticsearch B.V. Copying, publishing and/or distributing without written permission is strictly prohibited.-->

  <body>
    <!-- Google Tag Manager -->
    <script>dataLayer = [];</script><noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-58RLH5" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
    <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-58RLH5');</script>
    <!-- End Google Tag Manager -->

    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-12395217-16"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
      gtag('config', 'UA-12395217-16');
    </script>

    <!--BEGIN QUALTRICS WEBSITE FEEDBACK SNIPPET-->
    <script type="text/javascript">
      (function(){var g=function(e,h,f,g){
      this.get=function(a){for(var a=a+"=",c=document.cookie.split(";"),b=0,e=c.length;b<e;b++){for(var d=c[b];" "==d.charAt(0);)d=d.substring(1,d.length);if(0==d.indexOf(a))return d.substring(a.length,d.length)}return null};
      this.set=function(a,c){var b="",b=new Date;b.setTime(b.getTime()+6048E5);b="; expires="+b.toGMTString();document.cookie=a+"="+c+b+"; path=/; "};
      this.check=function(){var a=this.get(f);if(a)a=a.split(":");else if(100!=e)"v"==h&&(e=Math.random()>=e/100?0:100),a=[h,e,0],this.set(f,a.join(":"));else return!0;var c=a[1];if(100==c)return!0;switch(a[0]){case "v":return!1;case "r":return c=a[2]%Math.floor(100/c),a[2]++,this.set(f,a.join(":")),!c}return!0};
      this.go=function(){if(this.check()){var a=document.createElement("script");a.type="text/javascript";a.src=g;document.body&&document.body.appendChild(a)}};
      this.start=function(){var a=this;window.addEventListener?window.addEventListener("load",function(){a.go()},!1):window.attachEvent&&window.attachEvent("onload",function(){a.go()})}};
      try{(new g(100,"r","QSI_S_ZN_emkP0oSe9Qrn7kF","https://znemkp0ose9qrn7kf-elastic.siteintercept.qualtrics.com/WRSiteInterceptEngine/?Q_ZID=ZN_emkP0oSe9Qrn7kF")).start()}catch(i){}})();
    </script><div id="ZN_emkP0oSe9Qrn7kF"><!--DO NOT REMOVE-CONTENTS PLACED HERE--></div>
    <!--END WEBSITE FEEDBACK SNIPPET-->

    <div id="elastic-nav" style="display:none;"></div>
    <script src="https://www.elastic.co/elastic-nav.js"></script>

    <!-- Subnav -->
    <div>
      <div>
        <div class="tertiary-nav d-none d-md-block">
          <div class="container">
            <div class="p-t-b-15 d-flex justify-content-between nav-container">
              <div class="breadcrum-wrapper"><span><a href="/guide/" style="font-size: 14px; font-weight: 600; color: #000;">Docs</a></span></div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="main-container">
      <section id="content">
        <div class="content-wrapper">

          <section id="guide" lang="en">
            <div class="container">
              <div class="row">
                <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                  <!-- start body -->
                  <div class="page_header">
<strong>IMPORTANT</strong>: No additional bug fixes or documentation updates
will be released for this version. For the latest information, see the
<a href="../current/index.html">current release documentation</a>.
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch Guide [7.7]</a></span>
»
<span class="breadcrumb-link"><a href="rest-apis.html">REST APIs</a></span>
»
<span class="breadcrumb-link"><a href="search.html">Search APIs</a></span>
»
<span class="breadcrumb-node">Request Body Search</span>
</div>
<div class="navheader">
<span class="prev">
<a href="search-search.html">« Search API</a>
</span>
<span class="next">
<a href="async-search.html">Async search »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="search-request-body"></a>Request Body Search<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request-body.asciidoc">edit</a>
</h2>
</div></div></div>
<p>Specifies search criteria as request body parameters.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /twitter/_search
{
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1896.console"></div>
<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="search-request-body-api-request"></a>Request<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request-body.asciidoc">edit</a>
</h3>
</div></div></div>
<p><code class="literal">GET /&lt;index&gt;/_search
{
  "query": {&lt;parameters&gt;}
}</code></p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="search-request-body-api-desc"></a>Description<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request-body.asciidoc">edit</a>
</h3>
</div></div></div>
<p>The search request can be executed with a search DSL, which includes the
<a class="xref" href="query-dsl.html" title="Query DSL">Query DSL</a>, within its body.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="search-request-body-api-path-params"></a>Path parameters<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request-body.asciidoc">edit</a>
</h3>
</div></div></div>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
<code class="literal">&lt;index&gt;</code>
</span>
</dt>
<dd>
(Optional, string) Comma-separated list or wildcard expression of index names
used to limit the request.
</dd>
</dl>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="search-request-body-api-request-body"></a>Request body<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request-body.asciidoc">edit</a>
</h3>
</div></div></div>
<p>See the search API’s <a class="xref" href="search-search.html#search-search-api-request-body" title="Request body">request body parameters</a>.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_fast_check_for_any_matching_docs"></a>Fast check for any matching docs<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request-body.asciidoc">edit</a>
</h3>
</div></div></div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p><code class="literal">terminate_after</code> is always applied <span class="strong strong"><strong>after</strong></span> the <code class="literal">post_filter</code> and stops
       the query as well as the aggregation executions when enough hits have been
       collected on the shard. Though the doc count on aggregations may not reflect
       the <code class="literal">hits.total</code> in the response since aggregations are applied <span class="strong strong"><strong>before</strong></span> the
       post filtering.</p>
</div>
</div>
<p>In case we only want to know if there are any documents matching a
specific query, we can set the <code class="literal">size</code> to <code class="literal">0</code> to indicate that we are not
interested in the search results. Also we can set <code class="literal">terminate_after</code> to <code class="literal">1</code>
to indicate that the query execution can be terminated whenever the first
matching document was found (per shard).</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search?q=message:number&amp;size=0&amp;terminate_after=1</pre>
</div>
<div class="console_widget" data-snippet="snippets/1897.console"></div>
<p>The response will not contain any hits as the <code class="literal">size</code> was set to <code class="literal">0</code>. The
<code class="literal">hits.total</code> will be either equal to <code class="literal">0</code>, indicating that there were no
matching documents, or greater than <code class="literal">0</code> meaning that there were at least
as many documents matching the query when it was early terminated.
Also if the query was terminated early, the <code class="literal">terminated_early</code> flag will
be set to <code class="literal">true</code> in the response.</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
  "took": 3,
  "timed_out": false,
  "terminated_early": true,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped" : 0,
    "failed": 0
  },
  "hits": {
    "total" : {
        "value": 1,
        "relation": "eq"
    },
    "max_score": null,
    "hits": []
  }
}</pre>
</div>
<p>The <code class="literal">took</code> time in the response contains the milliseconds that this request
took for processing, beginning quickly after the node received the query, up
until all search related work is done and before the above JSON is returned
to the client. This means it includes the time spent waiting in thread pools,
executing a distributed search across the whole cluster and gathering all the
results.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-docvalue-fields"></a>Doc value fields<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/docvalue-fields.asciidoc">edit</a>
</h3>
</div></div></div>
<p>See <a class="xref" href="run-a-search.html#docvalue-fields" title="Doc value fields">doc value fields</a>.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-collapse"></a>Field Collapsing<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/collapse.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Allows to collapse search results based on field values.
The collapsing is done by selecting only the top sorted document per collapse key.
For instance the query below retrieves the best tweet for each user and sorts them by number of likes.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /twitter/_search
{
    "query": {
        "match": {
            "message": "elasticsearch"
        }
    },
    "collapse" : {
        "field" : "user" <a id="CO605-1"></a><i class="conum" data-value="1"></i>
    },
    "sort": ["likes"], <a id="CO605-2"></a><i class="conum" data-value="2"></i>
    "from": 10 <a id="CO605-3"></a><i class="conum" data-value="3"></i>
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1898.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO605-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>collapse the result set using the "user" field</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO605-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>sort the top docs by number of likes</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO605-3"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>define the offset of the first collapsed result</p>
</td>
</tr>
</table>
</div>
<div class="warning admon">
<div class="icon"></div>
<div class="admon_content">
<p>The total number of hits in the response indicates the number of matching documents without collapsing.
The total number of distinct group is unknown.</p>
</div>
</div>
<p>The field used for collapsing must be a single valued <a class="xref" href="keyword.html" title="Keyword datatype"><code class="literal">keyword</code></a> or <a class="xref" href="number.html" title="Numeric datatypes"><code class="literal">numeric</code></a> field with <a class="xref" href="doc-values.html" title="doc_values"><code class="literal">doc_values</code></a> activated</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>The collapsing is applied to the top hits only and does not affect aggregations.</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_expand_collapse_results"></a>Expand collapse results<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/collapse.asciidoc">edit</a>
</h4>
</div></div></div>
<p>It is also possible to expand each collapsed top hits with the <code class="literal">inner_hits</code> option.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /twitter/_search
{
    "query": {
        "match": {
            "message": "elasticsearch"
        }
    },
    "collapse" : {
        "field" : "user", <a id="CO606-1"></a><i class="conum" data-value="1"></i>
        "inner_hits": {
            "name": "last_tweets", <a id="CO606-2"></a><i class="conum" data-value="2"></i>
            "size": 5, <a id="CO606-3"></a><i class="conum" data-value="3"></i>
            "sort": [{ "date": "asc" }] <a id="CO606-4"></a><i class="conum" data-value="4"></i>
        },
        "max_concurrent_group_searches": 4 <a id="CO606-5"></a><i class="conum" data-value="5"></i>
    },
    "sort": ["likes"]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1899.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO606-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>collapse the result set using the "user" field</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO606-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>the name used for the inner hit section in the response</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO606-3"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>the number of inner_hits to retrieve per collapse key</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO606-4"><i class="conum" data-value="4"></i></a></p>
</td>
<td align="left" valign="top">
<p>how to sort the document inside each group</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO606-5"><i class="conum" data-value="5"></i></a></p>
</td>
<td align="left" valign="top">
<p>the number of concurrent requests allowed to retrieve the inner_hits` per group</p>
</td>
</tr>
</table>
</div>
<p>See <a class="xref" href="search-request-body.html#request-body-search-inner-hits" title="Inner hits">inner hits</a> for the complete list of supported options and the format of the response.</p>
<p>It is also possible to request multiple <code class="literal">inner_hits</code> for each collapsed hit.  This can be useful when you want to get
multiple representations of the collapsed hits.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /twitter/_search
{
    "query": {
        "match": {
            "message": "elasticsearch"
        }
    },
    "collapse" : {
        "field" : "user", <a id="CO607-1"></a><i class="conum" data-value="1"></i>
        "inner_hits": [
            {
                "name": "most_liked",  <a id="CO607-2"></a><i class="conum" data-value="2"></i>
                "size": 3,
                "sort": ["likes"]
            },
            {
                "name": "most_recent", <a id="CO607-3"></a><i class="conum" data-value="3"></i>
                "size": 3,
                "sort": [{ "date": "asc" }]
            }
        ]
    },
    "sort": ["likes"]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1900.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO607-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>collapse the result set using the "user" field</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO607-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>return the three most liked tweets for the user</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO607-3"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>return the three most recent tweets for the user</p>
</td>
</tr>
</table>
</div>
<p>The expansion of the group is done by sending an additional query for each
<code class="literal">inner_hit</code> request for each collapsed hit returned in the response.  This can significantly slow things down
if you have too many groups and/or <code class="literal">inner_hit</code> requests.</p>
<p>The <code class="literal">max_concurrent_group_searches</code> request parameter can be used to control
the maximum number of concurrent searches allowed in this phase.
The default is based on the number of data nodes and the default search thread pool size.</p>
<div class="warning admon">
<div class="icon"></div>
<div class="admon_content">
<p><code class="literal">collapse</code> cannot be used in conjunction with <a class="xref" href="search-request-body.html#request-body-search-scroll" title="Scroll">scroll</a>,
<a class="xref" href="search-request-body.html#request-body-search-rescore" title="Rescoring">rescore</a> or <a class="xref" href="search-request-body.html#request-body-search-search-after" title="Search After">search after</a>.</p>
</div>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_second_level_of_collapsing"></a>Second level of collapsing<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/collapse.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Second level of collapsing is also supported and is applied to <code class="literal">inner_hits</code>.
For example, the following request finds the top scored tweets for
each country, and within each country finds the top scored tweets
for each user.</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">GET /twitter/_search
{
    "query": {
        "match": {
            "message": "elasticsearch"
        }
    },
    "collapse" : {
        "field" : "country",
        "inner_hits" : {
            "name": "by_location",
            "collapse" : {"field" : "user"},
            "size": 3
        }
    }
}</pre>
</div>
<p>Response:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">{
    ...
    "hits": [
        {
            "_index": "twitter",
            "_type": "_doc",
            "_id": "9",
            "_score": ...,
            "_source": {...},
            "fields": {"country": ["UK"]},
            "inner_hits":{
                "by_location": {
                    "hits": {
                       ...,
                       "hits": [
                          {
                            ...
                            "fields": {"user" : ["user124"]}
                          },
                          {
                            ...
                            "fields": {"user" : ["user589"]}
                          },
                          {
                            ...
                             "fields": {"user" : ["user001"]}
                          }
                       ]
                    }
                 }
            }
        },
        {
            "_index": "twitter",
            "_type": "_doc",
            "_id": "1",
            "_score": ..,
            "_source": {...},
            "fields": {"country": ["Canada"]},
            "inner_hits":{
                "by_location": {
                    "hits": {
                       ...,
                       "hits": [
                          {
                            ...
                            "fields": {"user" : ["user444"]}
                          },
                          {
                            ...
                            "fields": {"user" : ["user1111"]}
                          },
                          {
                            ...
                             "fields": {"user" : ["user999"]}
                          }
                       ]
                    }
                 }
            }

        },
        ....
    ]
}</pre>
</div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>Second level of collapsing doesn’t allow <code class="literal">inner_hits</code>.</p>
</div>
</div>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-highlighting"></a>Highlighting<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Highlighters enable you to get highlighted snippets from one or more fields
in your search results so you can show users where the query matches are.
When you request highlights, the response contains an additional <code class="literal">highlight</code>
element for each search hit that includes the highlighted fields and the
highlighted fragments.</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>Highlighters don’t reflect the boolean logic of a query when extracting
 terms to highlight. Thus, for some complex boolean queries (e.g nested boolean
 queries, queries using <code class="literal">minimum_should_match</code> etc.), parts of documents may be
 highlighted that don’t correspond to query matches.</p>
</div>
</div>
<p>Highlighting requires the actual content of a field. If the field is not
stored (the mapping does not set <code class="literal">store</code> to <code class="literal">true</code>), the actual <code class="literal">_source</code> is
loaded and the relevant field is extracted from <code class="literal">_source</code>.</p>
<p>For example, to get highlights for the <code class="literal">content</code> field in each search hit
using the default highlighter, include a <code class="literal">highlight</code> object in
the request body that specifies the <code class="literal">content</code> field:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": { "content": "kimchy" }
    },
    "highlight" : {
        "fields" : {
            "content" : {}
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1901.console"></div>
<p>Elasticsearch supports three highlighters: <code class="literal">unified</code>, <code class="literal">plain</code>, and <code class="literal">fvh</code> (fast vector
highlighter). You can specify the highlighter <code class="literal">type</code> you want to use
for each field.</p>
<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="unified-highlighter"></a>Unified highlighter<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
</div></div></div>
<p>The <code class="literal">unified</code> highlighter uses the Lucene Unified Highlighter. This
highlighter breaks the text into sentences and uses the BM25 algorithm to score
individual sentences as if they were documents in the corpus. It also supports
accurate phrase and multi-term (fuzzy, prefix, regex) highlighting. This is the
default highlighter.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="plain-highlighter"></a>Plain highlighter<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
</div></div></div>
<p>The <code class="literal">plain</code> highlighter uses the standard Lucene highlighter. It attempts to
reflect the query matching logic in terms of understanding word importance and
any word positioning criteria in phrase queries.</p>
<div class="warning admon">
<div class="icon"></div>
<div class="admon_content">
<p>The <code class="literal">plain</code> highlighter works best for highlighting simple query matches in a
single field. To accurately reflect query logic, it creates a tiny in-memory
index and re-runs the original query criteria through Lucene’s query execution
planner to get access to low-level match information for the current document.
This is repeated for every field and every document that needs to be highlighted.
If you want to highlight a lot of fields in a lot of documents with complex
queries, we recommend using the <code class="literal">unified</code> highlighter on <code class="literal">postings</code> or <code class="literal">term_vector</code> fields.</p>
</div>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="fast-vector-highlighter"></a>Fast vector highlighter<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
</div></div></div>
<p>The <code class="literal">fvh</code> highlighter uses the Lucene Fast Vector highlighter.
This highlighter can be used on fields with <code class="literal">term_vector</code> set to
<code class="literal">with_positions_offsets</code> in the mapping. The fast vector highlighter:</p>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
Can be customized with  a <a class="xref" href="search-request-body.html#boundary-scanners"><code class="literal">boundary_scanner</code></a>.
</li>
<li class="listitem">
Requires setting <code class="literal">term_vector</code> to <code class="literal">with_positions_offsets</code> which
increases the size of the index
</li>
<li class="listitem">
Can combine matches from multiple fields into one result.  See
<code class="literal">matched_fields</code>
</li>
<li class="listitem">
Can assign different weights to matches at different positions allowing
for things like phrase matches being sorted above term matches when
highlighting a Boosting Query that boosts phrase matches over term matches
</li>
</ul>
</div>
<div class="warning admon">
<div class="icon"></div>
<div class="admon_content">
<p>The <code class="literal">fvh</code> highlighter does not support span queries. If you need support for
span queries, try an alternative highlighter, such as the <code class="literal">unified</code> highlighter.</p>
</div>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="offsets-strategy"></a>Offsets Strategy<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
</div></div></div>
<p>To create meaningful search snippets from the terms being queried,
the highlighter needs to know the start and end character offsets of each word
in the original text. These offsets can be obtained from:</p>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
The postings list. If <code class="literal">index_options</code> is set to <code class="literal">offsets</code> in the mapping,
the <code class="literal">unified</code> highlighter uses this information to highlight documents without
re-analyzing the text. It re-runs the original query directly on the postings
and extracts the matching offsets from the index, limiting the collection to
the highlighted documents. This is important if you have large fields because
it doesn’t require reanalyzing the text to be highlighted. It also requires less
disk space than using <code class="literal">term_vectors</code>.
</li>
<li class="listitem">
Term vectors. If <code class="literal">term_vector</code> information is provided by setting
<code class="literal">term_vector</code> to <code class="literal">with_positions_offsets</code> in the mapping, the <code class="literal">unified</code>
highlighter automatically uses the <code class="literal">term_vector</code> to highlight the field.
It’s fast especially for large fields (&gt; <code class="literal">1MB</code>) and for highlighting multi-term queries like
<code class="literal">prefix</code> or <code class="literal">wildcard</code> because it can access the dictionary of terms for each document.
The <code class="literal">fvh</code> highlighter always uses term vectors.
</li>
<li class="listitem">
Plain highlighting. This mode is used by the <code class="literal">unified</code> when there is no other alternative.
It creates a tiny in-memory index and re-runs the original query criteria through
Lucene’s query execution planner to get access to low-level match information on
the current document. This is repeated for every field and every document that
needs highlighting. The <code class="literal">plain</code> highlighter always uses plain highlighting.
</li>
</ul>
</div>
<div class="warning admon">
<div class="icon"></div>
<div class="admon_content">
<p>Plain highlighting for large texts may require substantial amount of time and memory.
To protect against this, the maximum number of text characters that will be analyzed has been
limited to 1000000. This default limit can be changed
for a particular index with the index setting <code class="literal">index.highlight.max_analyzed_offset</code>.</p>
</div>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="highlighting-settings"></a>Highlighting Settings<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Highlighting settings can be set on a global level and overridden at
the field level.</p>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
boundary_chars
</span>
</dt>
<dd>
A string that contains each boundary character.
Defaults to <code class="literal">.,!? \t\n</code>.
</dd>
<dt>
<span class="term">
boundary_max_scan
</span>
</dt>
<dd>
How far to scan for boundary characters. Defaults to <code class="literal">20</code>.
</dd>
</dl>
</div>
<div class="variablelist">
<a id="boundary-scanners"></a>
<dl class="variablelist">
<dt>
<span class="term">
boundary_scanner
</span>
</dt>
<dd>
<p>
Specifies how to break the highlighted fragments: <code class="literal">chars</code>,
<code class="literal">sentence</code>, or <code class="literal">word</code>. Only valid for the <code class="literal">unified</code> and <code class="literal">fvh</code> highlighters.
Defaults to <code class="literal">sentence</code> for the <code class="literal">unified</code> highlighter. Defaults to <code class="literal">chars</code> for
the <code class="literal">fvh</code> highlighter.
</p>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
<code class="literal">chars</code>
</span>
</dt>
<dd>
Use the characters specified by <code class="literal">boundary_chars</code> as highlighting
boundaries.  The <code class="literal">boundary_max_scan</code> setting controls how far to scan for
boundary characters. Only valid for the <code class="literal">fvh</code> highlighter.
</dd>
<dt>
<span class="term">
<code class="literal">sentence</code>
</span>
</dt>
<dd>
<p>
Break highlighted fragments at the next sentence boundary, as
determined by Java’s
<a href="https://docs.oracle.com/javase/8/docs/api/java/text/BreakIterator.html" class="ulink" target="_top">BreakIterator</a>.
You can specify the locale to use with <code class="literal">boundary_scanner_locale</code>.
</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>When used with the <code class="literal">unified</code> highlighter, the <code class="literal">sentence</code> scanner splits
sentences bigger than <code class="literal">fragment_size</code> at the first word boundary next to
<code class="literal">fragment_size</code>. You can set <code class="literal">fragment_size</code> to 0 to never split any sentence.</p>
</div>
</div>
</dd>
<dt>
<span class="term">
<code class="literal">word</code>
</span>
</dt>
<dd>
Break highlighted fragments at the next word boundary, as determined
by Java’s <a href="https://docs.oracle.com/javase/8/docs/api/java/text/BreakIterator.html" class="ulink" target="_top">BreakIterator</a>.
You can specify the locale to use with <code class="literal">boundary_scanner_locale</code>.
</dd>
</dl>
</div>
</dd>
<dt>
<span class="term">
boundary_scanner_locale
</span>
</dt>
<dd>
Controls which locale is used to search for sentence
and word boundaries. This parameter takes a form of a language tag,
e.g. <code class="literal">"en-US"</code>,  <code class="literal">"fr-FR"</code>, <code class="literal">"ja-JP"</code>. More info can be found in the
<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html#forLanguageTag-java.lang.String-" class="ulink" target="_top">Locale Language Tag</a>
documentation. The default value is <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html#ROOT" class="ulink" target="_top"> Locale.ROOT</a>.
</dd>
<dt>
<span class="term">
encoder
</span>
</dt>
<dd>
Indicates if the snippet should be HTML encoded:
<code class="literal">default</code> (no encoding) or <code class="literal">html</code> (HTML-escape the snippet text and then
insert the highlighting tags)
</dd>
<dt>
<span class="term">
fields
</span>
</dt>
<dd>
<p>
Specifies the fields to retrieve highlights for. You can use wildcards
to specify fields. For example, you could specify <code class="literal">comment_*</code> to
get highlights for all <a class="xref" href="text.html" title="Text datatype">text</a> and <a class="xref" href="keyword.html" title="Keyword datatype">keyword</a> fields
that start with <code class="literal">comment_</code>.
</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>Only text and keyword fields are highlighted when you use wildcards.
If you use a custom mapper and want to highlight on a field anyway, you
must explicitly specify that field name.</p>
</div>
</div>
</dd>
<dt>
<span class="term">
force_source
</span>
</dt>
<dd>
Highlight based on the source even if the field is
stored separately. Defaults to <code class="literal">false</code>.
</dd>
<dt>
<span class="term">
fragmenter
</span>
</dt>
<dd>
<p>
Specifies how text should be broken up in highlight
snippets: <code class="literal">simple</code> or <code class="literal">span</code>. Only valid for the <code class="literal">plain</code> highlighter.
Defaults to <code class="literal">span</code>.
</p>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
<code class="literal">simple</code>
</span>
</dt>
<dd>
Breaks up text into same-sized fragments.
</dd>
<dt>
<span class="term">
<code class="literal">span</code>
</span>
</dt>
<dd>
Breaks up text into same-sized fragments, but tries to avoid
breaking up text between highlighted terms. This is helpful when you’re
querying for phrases. Default.
</dd>
</dl>
</div>
</dd>
<dt>
<span class="term">
fragment_offset
</span>
</dt>
<dd>
Controls the margin from which you want to start
highlighting. Only valid when using the <code class="literal">fvh</code> highlighter.
</dd>
<dt>
<span class="term">
fragment_size
</span>
</dt>
<dd>
The size of the highlighted fragment in characters. Defaults
to 100.
</dd>
<dt>
<span class="term">
highlight_query
</span>
</dt>
<dd>
<p>
Highlight matches for a query other than the search
query. This is especially useful if you use a rescore query because
those are not taken into account by highlighting by default.
</p>
<div class="important admon">
<div class="icon"></div>
<div class="admon_content">
<p>Elasticsearch does not validate that <code class="literal">highlight_query</code> contains
the search query in any way so it is possible to define it so
legitimate query results are not highlighted. Generally, you should
include the search query as part of the <code class="literal">highlight_query</code>.</p>
</div>
</div>
</dd>
<dt>
<span class="term">
matched_fields
</span>
</dt>
<dd>
Combine matches on multiple fields to highlight a single field.
This is most intuitive for multifields that analyze the same string in different
ways.  All <code class="literal">matched_fields</code> must have <code class="literal">term_vector</code> set to
<code class="literal">with_positions_offsets</code>, but only the field to which
the matches are combined is loaded so only that field benefits from having
<code class="literal">store</code> set to <code class="literal">yes</code>. Only valid for the <code class="literal">fvh</code> highlighter.
</dd>
<dt>
<span class="term">
no_match_size
</span>
</dt>
<dd>
The amount of text you want to return from the beginning
of the field if there are no matching fragments to highlight. Defaults
to 0 (nothing is returned).
</dd>
<dt>
<span class="term">
number_of_fragments
</span>
</dt>
<dd>
The maximum number of fragments to return. If the
number of fragments is set to 0, no fragments are returned. Instead,
the entire field contents are highlighted and returned. This can be
handy when you need to highlight short texts such as a title or
address, but fragmentation is not required. If <code class="literal">number_of_fragments</code>
is 0, <code class="literal">fragment_size</code> is ignored. Defaults to 5.
</dd>
<dt>
<span class="term">
order
</span>
</dt>
<dd>
Sorts highlighted fragments by score when set to <code class="literal">score</code>.  By default,
fragments will be output in the order they appear in the field (order: <code class="literal">none</code>).
Setting this option to <code class="literal">score</code> will output the most relevant fragments first.
Each highlighter applies its own logic to compute relevancy scores. See
the document <a class="xref" href="search-request-body.html#highlighter-internal-work" title="How highlighters work internally">How highlighters work internally</a>
for more details how different highlighters find the best fragments.
</dd>
<dt>
<span class="term">
phrase_limit
</span>
</dt>
<dd>
Controls the number of matching phrases in a document that are
considered. Prevents the <code class="literal">fvh</code> highlighter from analyzing too many phrases
and consuming too much memory. When using <code class="literal">matched_fields</code>, <code class="literal">phrase_limit</code>
phrases per matched field are considered. Raising the limit increases query
time and consumes more memory. Only supported by the <code class="literal">fvh</code> highlighter.
Defaults to 256.
</dd>
<dt>
<span class="term">
pre_tags
</span>
</dt>
<dd>
Use in conjunction with <code class="literal">post_tags</code> to define the HTML tags
to use for the highlighted text. By default, highlighted text is wrapped
in <code class="literal">&lt;em&gt;</code> and <code class="literal">&lt;/em&gt;</code> tags. Specify as an array of strings.
</dd>
<dt>
<span class="term">
post_tags
</span>
</dt>
<dd>
Use in conjunction with <code class="literal">pre_tags</code> to define the HTML tags
to use for the highlighted text. By default, highlighted text is wrapped
in <code class="literal">&lt;em&gt;</code> and <code class="literal">&lt;/em&gt;</code> tags. Specify as an array of strings.
</dd>
<dt>
<span class="term">
require_field_match
</span>
</dt>
<dd>
By default, only fields that contains a query match are
highlighted. Set <code class="literal">require_field_match</code> to <code class="literal">false</code> to highlight all fields.
Defaults to <code class="literal">true</code>.
</dd>
<dt>
<span class="term">
tags_schema
</span>
</dt>
<dd>
<p>
Set to <code class="literal">styled</code> to use the built-in tag schema. The <code class="literal">styled</code>
schema defines the following <code class="literal">pre_tags</code> and defines <code class="literal">post_tags</code> as
<code class="literal">&lt;/em&gt;</code>.
</p>
<div class="pre_wrapper lang-html">
<pre class="programlisting prettyprint lang-html">&lt;em class="hlt1"&gt;, &lt;em class="hlt2"&gt;, &lt;em class="hlt3"&gt;,
&lt;em class="hlt4"&gt;, &lt;em class="hlt5"&gt;, &lt;em class="hlt6"&gt;,
&lt;em class="hlt7"&gt;, &lt;em class="hlt8"&gt;, &lt;em class="hlt9"&gt;,
&lt;em class="hlt10"&gt;</pre>
</div>
</dd>
</dl>
</div>
<div class="variablelist">
<a id="highlighter-type"></a>
<dl class="variablelist">
<dt>
<span class="term">
type
</span>
</dt>
<dd>
The highlighter to use: <code class="literal">unified</code>, <code class="literal">plain</code>, or <code class="literal">fvh</code>. Defaults to
<code class="literal">unified</code>.
</dd>
</dl>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="highlighting-examples"></a>Highlighting Examples<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
</div></div></div>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<a class="xref" href="search-request-body.html#override-global-settings" title="Override global settings">Override global settings</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#specify-highlight-query" title="Specify a highlight query">Specify a highlight query</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#set-highlighter-type" title="Set highlighter type">Set highlighter type</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#configure-tags" title="Configure highlighting tags">Configure highlighting tags</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#highlight-source" title="Highlight on source">Highlight source</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#highlight-all" title="Highlight in all fields">Highlight all fields</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#matched-fields" title="Combine matches on multiple fields">Combine matches on multiple fields</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#explicit-field-order" title="Explicitly order highlighted fields">Explicitly order highlighted fields</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#control-highlighted-frags" title="Control highlighted fragments">Control highlighted fragments</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#highlight-postings-list" title="Highlight using the postings list">Highlight using the postings list</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#specify-fragmenter" title="Specify a fragmenter for the plain highlighter">Specify a fragmenter for the plain highlighter</a>
</li>
</ul>
</div>
<h4>
<a id="override-global-settings"></a>Override global settings<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
<p>You can specify highlighter settings globally and selectively override them for
individual fields.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": { "user": "kimchy" }
    },
    "highlight" : {
        "number_of_fragments" : 3,
        "fragment_size" : 150,
        "fields" : {
            "body" : { "pre_tags" : ["&lt;em&gt;"], "post_tags" : ["&lt;/em&gt;"] },
            "blog.title" : { "number_of_fragments" : 0 },
            "blog.author" : { "number_of_fragments" : 0 },
            "blog.comment" : { "number_of_fragments" : 5, "order" : "score" }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1902.console"></div>
<h4>
<a id="specify-highlight-query"></a>Specify a highlight query<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
<p>You can specify a <code class="literal">highlight_query</code> to take additional information into account
when highlighting. For example, the following query includes both the search
query and rescore query in the <code class="literal">highlight_query</code>. Without the <code class="literal">highlight_query</code>,
highlighting would only take the search query into account.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": {
            "comment": {
                "query": "foo bar"
            }
        }
    },
    "rescore": {
        "window_size": 50,
        "query": {
            "rescore_query" : {
                "match_phrase": {
                    "comment": {
                        "query": "foo bar",
                        "slop": 1
                    }
                }
            },
            "rescore_query_weight" : 10
        }
    },
    "_source": false,
    "highlight" : {
        "order" : "score",
        "fields" : {
            "comment" : {
                "fragment_size" : 150,
                "number_of_fragments" : 3,
                "highlight_query": {
                    "bool": {
                        "must": {
                            "match": {
                                "comment": {
                                    "query": "foo bar"
                                }
                            }
                        },
                        "should": {
                            "match_phrase": {
                                "comment": {
                                    "query": "foo bar",
                                    "slop": 1,
                                    "boost": 10.0
                                }
                            }
                        },
                        "minimum_should_match": 0
                    }
                }
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1903.console"></div>
<h4>
<a id="set-highlighter-type"></a>Set highlighter type<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
<p>The <code class="literal">type</code> field allows to force a specific highlighter type.
The allowed values are: <code class="literal">unified</code>, <code class="literal">plain</code> and <code class="literal">fvh</code>.
The following is an example that forces the use of the plain highlighter:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": { "user": "kimchy" }
    },
    "highlight" : {
        "fields" : {
            "comment" : {"type" : "plain"}
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1904.console"></div>
<h4>
<a id="configure-tags"></a>Configure highlighting tags<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
<p>By default, the highlighting will wrap highlighted text in <code class="literal">&lt;em&gt;</code> and
<code class="literal">&lt;/em&gt;</code>. This can be controlled by setting <code class="literal">pre_tags</code> and <code class="literal">post_tags</code>,
for example:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": { "user": "kimchy" }
    },
    "highlight" : {
        "pre_tags" : ["&lt;tag1&gt;"],
        "post_tags" : ["&lt;/tag1&gt;"],
        "fields" : {
            "body" : {}
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1905.console"></div>
<p>When using the fast vector highlighter, you can specify additional tags and the
"importance" is ordered.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": { "user": "kimchy" }
    },
    "highlight" : {
        "pre_tags" : ["&lt;tag1&gt;", "&lt;tag2&gt;"],
        "post_tags" : ["&lt;/tag1&gt;", "&lt;/tag2&gt;"],
        "fields" : {
            "body" : {}
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1906.console"></div>
<p>You can also use the built-in <code class="literal">styled</code> tag schema:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": { "user": "kimchy" }
    },
    "highlight" : {
        "tags_schema" : "styled",
        "fields" : {
            "comment" : {}
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1907.console"></div>
<h4>
<a id="highlight-source"></a>Highlight on source<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
<p>Forces the highlighting to highlight fields based on the source even if fields
are stored separately. Defaults to <code class="literal">false</code>.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": { "user": "kimchy" }
    },
    "highlight" : {
        "fields" : {
            "comment" : {"force_source" : true}
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1908.console"></div>
<h4>
<a id="highlight-all"></a>Highlight in all fields<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
<p>By default, only fields that contains a query match are highlighted. Set
<code class="literal">require_field_match</code> to <code class="literal">false</code> to highlight all fields.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": { "user": "kimchy" }
    },
    "highlight" : {
        "require_field_match": false,
        "fields": {
                "body" : { "pre_tags" : ["&lt;em&gt;"], "post_tags" : ["&lt;/em&gt;"] }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1909.console"></div>
<h4>
<a id="matched-fields"></a>Combine matches on multiple fields<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
<div class="warning admon">
<div class="icon"></div>
<div class="admon_content">
<p>This is only supported by the <code class="literal">fvh</code> highlighter</p>
</div>
</div>
<p>The Fast Vector Highlighter can combine matches on multiple fields to
highlight a single field.  This is most intuitive for multifields that
analyze the same string in different ways.  All <code class="literal">matched_fields</code> must have
<code class="literal">term_vector</code> set to <code class="literal">with_positions_offsets</code> but only the field to which
the matches are combined is loaded so only that field would benefit from having
<code class="literal">store</code> set to <code class="literal">yes</code>.</p>
<p>In the following examples, <code class="literal">comment</code> is analyzed by the <code class="literal">english</code>
analyzer and <code class="literal">comment.plain</code> is analyzed by the <code class="literal">standard</code> analyzer.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query": {
        "query_string": {
            "query": "comment.plain:running scissors",
            "fields": ["comment"]
        }
    },
    "highlight": {
        "order": "score",
        "fields": {
            "comment": {
                "matched_fields": ["comment", "comment.plain"],
                "type" : "fvh"
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1910.console"></div>
<p>The above matches both "run with scissors" and "running with scissors"
and would highlight "running" and "scissors" but not "run". If both
phrases appear in a large document then "running with scissors" is
sorted above "run with scissors" in the fragments list because there
are more matches in that fragment.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query": {
        "query_string": {
            "query": "running scissors",
            "fields": ["comment", "comment.plain^10"]
        }
    },
    "highlight": {
        "order": "score",
        "fields": {
            "comment": {
                "matched_fields": ["comment", "comment.plain"],
                "type" : "fvh"
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1911.console"></div>
<p>The above highlights "run" as well as "running" and "scissors" but
still sorts "running with scissors" above "run with scissors" because
the plain match ("running") is boosted.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query": {
        "query_string": {
            "query": "running scissors",
            "fields": ["comment", "comment.plain^10"]
        }
    },
    "highlight": {
        "order": "score",
        "fields": {
            "comment": {
                "matched_fields": ["comment.plain"],
                "type" : "fvh"
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1912.console"></div>
<p>The above query wouldn’t highlight "run" or "scissor" but shows that
it is just fine not to list the field to which the matches are combined
(<code class="literal">comment</code>) in the matched fields.</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>Technically it is also fine to add fields to <code class="literal">matched_fields</code> that
don’t share the same underlying string as the field to which the matches
are combined.  The results might not make much sense and if one of the
matches is off the end of the text then the whole query will fail.</p>
</div>
</div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>There is a small amount of overhead involved with setting
<code class="literal">matched_fields</code> to a non-empty array so always prefer</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">    "highlight": {
        "fields": {
            "comment": {}
        }
    }</pre>
</div>
<p>to</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">    "highlight": {
        "fields": {
            "comment": {
                "matched_fields": ["comment"],
                "type" : "fvh"
            }
        }
    }</pre>
</div>
</div>
</div>
<h4>
<a id="explicit-field-order"></a>Explicitly order highlighted fields<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
<p>Elasticsearch highlights the fields in the order that they are sent, but per the
JSON spec, objects are unordered.  If you need to be explicit about the order
in which fields are highlighted specify the <code class="literal">fields</code> as an array:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "highlight": {
        "fields": [
            { "title": {} },
            { "text": {} }
        ]
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1913.console"></div>
<p>None of the highlighters built into Elasticsearch care about the order that the
fields are highlighted but a plugin might.</p>
<h4>
<a id="control-highlighted-frags"></a>Control highlighted fragments<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
<p>Each field highlighted can control the size of the highlighted fragment
in characters (defaults to <code class="literal">100</code>), and the maximum number of fragments
to return (defaults to <code class="literal">5</code>).
For example:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": { "user": "kimchy" }
    },
    "highlight" : {
        "fields" : {
            "comment" : {"fragment_size" : 150, "number_of_fragments" : 3}
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1914.console"></div>
<p>On top of this it is possible to specify that highlighted fragments need
to be sorted by score:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": { "user": "kimchy" }
    },
    "highlight" : {
        "order" : "score",
        "fields" : {
            "comment" : {"fragment_size" : 150, "number_of_fragments" : 3}
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1915.console"></div>
<p>If the <code class="literal">number_of_fragments</code> value is set to <code class="literal">0</code> then no fragments are
produced, instead the whole content of the field is returned, and of
course it is highlighted. This can be very handy if short texts (like
document title or address) need to be highlighted but no fragmentation
is required. Note that <code class="literal">fragment_size</code> is ignored in this case.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": { "user": "kimchy" }
    },
    "highlight" : {
        "fields" : {
            "body" : {},
            "blog.title" : {"number_of_fragments" : 0}
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1916.console"></div>
<p>When using <code class="literal">fvh</code> one can use <code class="literal">fragment_offset</code>
parameter to control the margin to start highlighting from.</p>
<p>In the case where there is no matching fragment to highlight, the default is
to not return anything. Instead, we can return a snippet of text from the
beginning of the field by setting <code class="literal">no_match_size</code> (default <code class="literal">0</code>) to the length
of the text that you want returned. The actual length may be shorter or longer than
specified as it tries to break on a word boundary.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match": { "user": "kimchy" }
    },
    "highlight" : {
        "fields" : {
            "comment" : {
                "fragment_size" : 150,
                "number_of_fragments" : 3,
                "no_match_size": 150
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1917.console"></div>
<h4>
<a id="highlight-postings-list"></a>Highlight using the postings list<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
<p>Here is an example of setting the <code class="literal">comment</code> field in the index mapping to
allow for highlighting using the postings:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT /example
{
  "mappings": {
    "properties": {
      "comment" : {
        "type": "text",
        "index_options" : "offsets"
      }
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1918.console"></div>
<p>Here is an example of setting the <code class="literal">comment</code> field to allow for
highlighting using the <code class="literal">term_vectors</code> (this will cause the index to be bigger):</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT /example
{
  "mappings": {
    "properties": {
      "comment" : {
        "type": "text",
        "term_vector" : "with_positions_offsets"
      }
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1919.console"></div>
<h4>
<a id="specify-fragmenter"></a>Specify a fragmenter for the plain highlighter<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighting.asciidoc">edit</a>
</h4>
<p>When using the <code class="literal">plain</code> highlighter, you can choose between the <code class="literal">simple</code> and
<code class="literal">span</code> fragmenters:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET twitter/_search
{
    "query" : {
        "match_phrase": { "message": "number 1" }
    },
    "highlight" : {
        "fields" : {
            "message" : {
                "type": "plain",
                "fragment_size" : 15,
                "number_of_fragments" : 3,
                "fragmenter": "simple"
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1920.console"></div>
<p>Response:</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
    ...
    "hits": {
        "total" : {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 1.6011951,
        "hits": [
            {
                "_index": "twitter",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.6011951,
                "_source": {
                    "user": "test",
                    "message": "some message with the number 1",
                    "date": "2009-11-15T14:12:12",
                    "likes": 1
                },
                "highlight": {
                    "message": [
                        " with the &lt;em&gt;number&lt;/em&gt;",
                        " &lt;em&gt;1&lt;/em&gt;"
                    ]
                }
            }
        ]
    }
}</pre>
</div>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET twitter/_search
{
    "query" : {
        "match_phrase": { "message": "number 1" }
    },
    "highlight" : {
        "fields" : {
            "message" : {
                "type": "plain",
                "fragment_size" : 15,
                "number_of_fragments" : 3,
                "fragmenter": "span"
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1921.console"></div>
<p>Response:</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
    ...
    "hits": {
        "total" : {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 1.6011951,
        "hits": [
            {
                "_index": "twitter",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.6011951,
                "_source": {
                    "user": "test",
                    "message": "some message with the number 1",
                    "date": "2009-11-15T14:12:12",
                    "likes": 1
                },
                "highlight": {
                    "message": [
                        " with the &lt;em&gt;number&lt;/em&gt; &lt;em&gt;1&lt;/em&gt;"
                    ]
                }
            }
        ]
    }
}</pre>
</div>
<p>If the <code class="literal">number_of_fragments</code> option is set to <code class="literal">0</code>,
<code class="literal">NullFragmenter</code> is used which does not fragment the text at all.
This is useful for highlighting the entire contents of a document or field.</p>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="highlighter-internal-work"></a>How highlighters work internally<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighters-internal.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Given a query and a text (the content of a document field), the goal of a
highlighter is to find the best text fragments for the query, and highlight
the query terms in the found fragments. For this, a highlighter needs to
address several questions:</p>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
How break a text into fragments?
</li>
<li class="listitem">
How to find the best fragments among all fragments?
</li>
<li class="listitem">
How to highlight the query terms in a fragment?
</li>
</ul>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_how_to_break_a_text_into_fragments"></a>How to break a text into fragments?<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighters-internal.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Relevant settings: <code class="literal">fragment_size</code>, <code class="literal">fragmenter</code>, <code class="literal">type</code> of highlighter,
<code class="literal">boundary_chars</code>, <code class="literal">boundary_max_scan</code>, <code class="literal">boundary_scanner</code>, <code class="literal">boundary_scanner_locale</code>.</p>
<p>Plain highlighter begins with analyzing the text using the given analyzer,
and creating a token stream from it. Plain highlighter uses a very simple
algorithm to break the token stream into fragments. It loops through terms in the token stream,
and every time the current term’s end_offset exceeds <code class="literal">fragment_size</code> multiplied by the number of
created fragments, a new fragment is created. A little more computation is done with using <code class="literal">span</code>
fragmenter to avoid breaking up text between highlighted terms. But overall, since the breaking is
done only by <code class="literal">fragment_size</code>, some fragments can be quite odd, e.g. beginning
with a punctuation mark.</p>
<p>Unified or FVH highlighters do a better job of breaking up a text into
fragments by utilizing Java’s <code class="literal">BreakIterator</code>. This ensures that a fragment
is a valid sentence as long as <code class="literal">fragment_size</code> allows for this.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_how_to_find_the_best_fragments"></a>How to find the best fragments?<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighters-internal.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Relevant settings: <code class="literal">number_of_fragments</code>.</p>
<p>To find the best, most relevant, fragments, a highlighter needs to score
each fragment in respect to the given query. The goal is to score only those
terms that participated in generating the <em>hit</em> on the document.
For some complex queries, this is still work in progress.</p>
<p>The plain highlighter creates an in-memory index from the current token stream,
and re-runs the original query criteria through Lucene’s query execution planner
to get access to low-level match information for the current text.
For more complex queries the original query could be converted to a span query,
as span queries can handle phrases more accurately. Then this obtained low-level match
information is used to score each individual fragment. The scoring method of the plain
highlighter is quite simple. Each fragment is scored by the number of unique
query terms found in this fragment. The score of individual term is equal to its boost,
which is by default is 1. Thus, by default, a fragment that contains one unique query term,
will get a score of 1; and a fragment that contains two unique query terms,
will get a score of 2 and so on. The fragments are then sorted by their scores,
so the highest scored fragments will be output first.</p>
<p>FVH doesn’t need to analyze the text and build an in-memory index, as it uses
pre-indexed document term vectors, and finds among them terms that correspond to the query.
FVH scores each fragment by the number of query terms found in this fragment.
Similarly to plain highlighter, score of individual term is equal to its boost value.
In contrast to plain highlighter, all query terms are counted, not only unique terms.</p>
<p>Unified highlighter can use pre-indexed term vectors or pre-indexed terms offsets,
if they are available. Otherwise, similar to Plain Highlighter, it has to create
an in-memory index from the text. Unified highlighter uses the BM25 scoring model
to score fragments.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_how_to_highlight_the_query_terms_in_a_fragment"></a>How to highlight the query terms in a fragment?<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighters-internal.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Relevant settings:  <code class="literal">pre-tags</code>, <code class="literal">post-tags</code>.</p>
<p>The goal is to highlight only those terms that participated in generating the <em>hit</em> on the document.
For some complex boolean queries, this is still work in progress, as highlighters don’t reflect
the boolean logic of a query and only extract leaf (terms, phrases, prefix etc) queries.</p>
<p>Plain highlighter given the token stream and the original text, recomposes the original text to
highlight only terms from the token stream that are contained in the low-level match information
structure from the previous step.</p>
<p>FVH and unified highlighter use intermediate data structures to represent
fragments in some raw form, and then populate them with actual text.</p>
<p>A highlighter uses <code class="literal">pre-tags</code>, <code class="literal">post-tags</code> to encode highlighted terms.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_an_example_of_the_work_of_the_unified_highlighter"></a>An example of the work of the unified highlighter<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/highlighters-internal.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Let’s look in more details how unified highlighter works.</p>
<p>First, we create a index with a text field <code class="literal">content</code>, that will be indexed
using <code class="literal">english</code> analyzer, and will be indexed without offsets or term vectors.</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">PUT test_index
{
    "mappings": {
        "properties": {
            "content" : {
                "type" : "text",
                "analyzer" : "english"
            }
        }
    }
}</pre>
</div>
<p>We put the following document into the index:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">PUT test_index/_doc/doc1
{
  "content" : "For you I'm only a fox like a hundred thousand other foxes. But if you tame me, we'll need each other. You'll be the only boy in the world for me. I'll be the only fox in the world for you."
}</pre>
</div>
<p>And we ran the following query with a highlight request:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">GET test_index/_search
{
    "query": {
        "match_phrase" : {"content" : "only fox"}
    },
    "highlight": {
        "type" : "unified",
        "number_of_fragments" : 3,
        "fields": {
            "content": {}
        }
    }
}</pre>
</div>
<p>After <code class="literal">doc1</code> is found as a hit for this query, this hit will be passed to the
unified highlighter for highlighting the field <code class="literal">content</code> of the document.
Since the field <code class="literal">content</code> was not indexed either with offsets or term vectors,
its raw field value will be analyzed, and in-memory index will be built from
the terms that match the query:</p>
<pre class="literallayout">{"token":"onli","start_offset":12,"end_offset":16,"position":3},
{"token":"fox","start_offset":19,"end_offset":22,"position":5},
{"token":"fox","start_offset":53,"end_offset":58,"position":11},
{"token":"onli","start_offset":117,"end_offset":121,"position":24},
{"token":"onli","start_offset":159,"end_offset":163,"position":34},
{"token":"fox","start_offset":164,"end_offset":167,"position":35}</pre>

<p>Our complex phrase query will be converted to the span query:
<code class="literal">spanNear([text:onli, text:fox], 0, true)</code>, meaning that we are looking for
terms "onli: and "fox" within 0 distance from each other, and in the given
order. The span query will be run against the created before in-memory index,
to find the following match:</p>
<pre class="literallayout">{"term":"onli", "start_offset":159, "end_offset":163},
{"term":"fox", "start_offset":164, "end_offset":167}</pre>

<p>In our example, we have got a single match, but there could be several matches.
Given the matches, the unified highlighter breaks the text of the field into
so called "passages". Each passage must contain at least one match.
The unified highlighter with the use of Java’s <code class="literal">BreakIterator</code> ensures that each
passage represents a full sentence as long as it doesn’t exceed <code class="literal">fragment_size</code>.
For our example, we have got a single passage with the following properties
(showing only a subset of the properties here):</p>
<pre class="literallayout">Passage:
    startOffset: 147
    endOffset: 189
    score: 3.7158387
    matchStarts: [159, 164]
    matchEnds: [163, 167]
    numMatches: 2</pre>

<p>Notice how a passage has a score, calculated using the BM25 scoring formula
adapted for passages. Scores allow us to choose the best scoring
passages if there are more passages available than the requested
by the user <code class="literal">number_of_fragments</code>. Scores also let us to sort passages by
<code class="literal">order: "score"</code> if requested by the user.</p>
<p>As the final step, the unified highlighter will extract from the field’s text
a string corresponding to each passage:</p>
<pre class="literallayout">"I'll be the only fox in the world for you."</pre>

<p>and will format with the tags &lt;em&gt; and &lt;/em&gt; all matches in this string
using the passages’s <code class="literal">matchStarts</code> and <code class="literal">matchEnds</code> information:</p>
<pre class="literallayout">I'll be the &lt;em&gt;only&lt;/em&gt; &lt;em&gt;fox&lt;/em&gt; in the world for you.</pre>

<p>This kind of formatted strings are the final result of the highlighter returned
to the user.</p>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-index-boost"></a>Index Boost<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/index-boost.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Allows to configure different boost level per index when searching
across more than one indices. This is very handy when hits coming from
one index matter more than hits coming from another index (think social
graph where each user has an index).</p>
<div class="warning admon">
<div class="icon"></div>
<div class="admon_content">
<h3>Deprecated in 5.2.0.</h3>
<p>This format is deprecated. Please use array format instead.</p>
</div>
</div>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "indices_boost" : {
        "index1" : 1.4,
        "index2" : 1.3
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1922.console"></div>
<p>You can also specify it as an array to control the order of boosts.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "indices_boost" : [
        { "alias1" : 1.4 },
        { "index*" : 1.3 }
    ]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1923.console"></div>
<p>This is important when you use aliases or wildcard expression.
If multiple matches are found, the first match will be used.
For example, if an index is included in both <code class="literal">alias1</code> and <code class="literal">index*</code>, boost value of <code class="literal">1.4</code> is applied.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-inner-hits"></a>Inner hits<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/inner-hits.asciidoc">edit</a>
</h3>
</div></div></div>
<p>The <a class="xref" href="parent-join.html" title="Join datatype">parent-join</a> and <a class="xref" href="nested.html" title="Nested datatype">nested</a> features allow the return of documents that
have matches in a different scope. In the parent/child case, parent documents are returned based on matches in child
documents or child documents are returned based on matches in parent documents. In the nested case, documents are returned
based on matches in nested inner objects.</p>
<p>In both cases, the actual matches in the different scopes that caused a document to be returned are hidden. In many cases,
it’s very useful to know which inner nested objects (in the case of nested) or children/parent documents (in the case
of parent/child) caused certain information to be returned. The inner hits feature can be used for this. This feature
returns per search hit in the search response additional nested hits that caused a search hit to match in a different scope.</p>
<p>Inner hits can be used by defining an <code class="literal">inner_hits</code> definition on a <code class="literal">nested</code>, <code class="literal">has_child</code> or <code class="literal">has_parent</code> query and filter.
The structure looks like this:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">"&lt;query&gt;" : {
    "inner_hits" : {
        &lt;inner_hits_options&gt;
    }
}</pre>
</div>
<p>If <code class="literal">inner_hits</code> is defined on a query that supports it then each search hit will contain an <code class="literal">inner_hits</code> json object with the following structure:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">"hits": [
     {
        "_index": ...,
        "_type": ...,
        "_id": ...,
        "inner_hits": {
           "&lt;inner_hits_name&gt;": {
              "hits": {
                 "total": ...,
                 "hits": [
                    {
                       "_type": ...,
                       "_id": ...,
                       ...
                    },
                    ...
                 ]
              }
           }
        },
        ...
     },
     ...
]</pre>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_options_7"></a>Options<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/inner-hits.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Inner hits support the following options:</p>
<div class="informaltable">
<table border="0" cellpadding="4px">
<colgroup>
<col>
<col>
</colgroup>
<tbody valign="top">
<tr>
<td valign="top">
<p>
<code class="literal">from</code>
</p>
</td>
<td valign="top">
<p>
The offset from where the first hit to fetch for each <code class="literal">inner_hits</code> in the returned regular search hits.
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
<code class="literal">size</code>
</p>
</td>
<td valign="top">
<p>
The maximum number of hits to return per <code class="literal">inner_hits</code>. By default the top three matching hits are returned.
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
<code class="literal">sort</code>
</p>
</td>
<td valign="top">
<p>
How the inner hits should be sorted per <code class="literal">inner_hits</code>. By default the hits are sorted by the score.
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
<code class="literal">name</code>
</p>
</td>
<td valign="top">
<p>
The name to be used for the particular inner hit definition in the response. Useful when multiple inner hits
have been defined in a single search request. The default depends in which query the inner hit is defined.
For <code class="literal">has_child</code> query and filter this is the child type, <code class="literal">has_parent</code> query and filter this is the parent type
and the nested query and filter this is the nested path.
</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>Inner hits also supports the following per document features:</p>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<a class="xref" href="search-request-body.html#request-body-search-highlighting" title="Highlighting">Highlighting</a>
</li>
<li class="listitem">
<a class="xref" href="search-search.html#request-body-search-explain">Explain</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#request-body-search-source-filtering" title="Source filtering">Source filtering</a>
</li>
<li class="listitem">
<a class="xref" href="search-request-body.html#request-body-search-script-fields" title="Script Fields">Script fields</a>
</li>
<li class="listitem">
<a class="xref" href="run-a-search.html#docvalue-fields" title="Doc value fields">Doc value fields</a>
</li>
<li class="listitem">
<a class="xref" href="search-search.html#request-body-search-version">Include versions</a>
</li>
<li class="listitem">
<a class="xref" href="search-search.html#request-body-search-seq-no-primary-term">Include Sequence Numbers and Primary Terms</a>
</li>
</ul>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="nested-inner-hits"></a>Nested inner hits<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/inner-hits.asciidoc">edit</a>
</h4>
</div></div></div>
<p>The nested <code class="literal">inner_hits</code> can be used to include nested inner objects as inner hits to a search hit.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT test
{
  "mappings": {
    "properties": {
      "comments": {
        "type": "nested"
      }
    }
  }
}

PUT test/_doc/1?refresh
{
  "title": "Test title",
  "comments": [
    {
      "author": "kimchy",
      "number": 1
    },
    {
      "author": "nik9000",
      "number": 2
    }
  ]
}

POST test/_search
{
  "query": {
    "nested": {
      "path": "comments",
      "query": {
        "match": {"comments.number" : 2}
      },
      "inner_hits": {} <a id="CO608-1"></a><i class="conum" data-value="1"></i>
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1924.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO608-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>The inner hit definition in the nested query. No other options need to be defined.</p>
</td>
</tr>
</table>
</div>
<p>An example of a response snippet that could be generated from the above search request:</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
  ...,
  "hits": {
    "total" : {
        "value": 1,
        "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [
      {
        "_index": "test",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0,
        "_source": ...,
        "inner_hits": {
          "comments": { <a id="CO609-1"></a><i class="conum" data-value="1"></i>
            "hits": {
              "total" : {
                  "value": 1,
                  "relation": "eq"
              },
              "max_score": 1.0,
              "hits": [
                {
                  "_index": "test",
                  "_type": "_doc",
                  "_id": "1",
                  "_nested": {
                    "field": "comments",
                    "offset": 1
                  },
                  "_score": 1.0,
                  "_source": {
                    "author": "nik9000",
                    "number": 2
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO609-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>The name used in the inner hit definition in the search request. A custom key can be used via the <code class="literal">name</code> option.</p>
</td>
</tr>
</table>
</div>
<p>The <code class="literal">_nested</code> metadata is crucial in the above example, because it defines from what inner nested object this inner hit
came from. The <code class="literal">field</code> defines the object array field the nested hit is from and the <code class="literal">offset</code> relative to its location
in the <code class="literal">_source</code>. Due to sorting and scoring the actual location of the hit objects in the <code class="literal">inner_hits</code> is usually
different than the location a nested inner object was defined.</p>
<p>By default the <code class="literal">_source</code> is returned also for the hit objects in <code class="literal">inner_hits</code>, but this can be changed. Either via
<code class="literal">_source</code> filtering feature part of the source can be returned or be disabled. If stored fields are defined on the
nested level these can also be returned via the <code class="literal">fields</code> feature.</p>
<p>An important default is that the <code class="literal">_source</code> returned in hits inside <code class="literal">inner_hits</code> is relative to the <code class="literal">_nested</code> metadata.
So in the above example only the comment part is returned per nested hit and not the entire source of the top level
document that contained the comment.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="nested-inner-hits-source"></a>Nested inner hits and <code class="literal">_source</code><a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/inner-hits.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Nested document don’t have a <code class="literal">_source</code> field, because the entire source of document is stored with the root document under
its <code class="literal">_source</code> field. To include the source of just the nested document, the source of the root document is parsed and just
the relevant bit for the nested document is included as source in the inner hit. Doing this for each matching nested document
has an impact on the time it takes to execute the entire search request, especially when <code class="literal">size</code> and the inner hits' <code class="literal">size</code>
are set higher than the default. To avoid the relatively expensive source extraction for nested inner hits, one can disable
including the source and solely rely on doc values fields. Like this:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT test
{
  "mappings": {
    "properties": {
      "comments": {
        "type": "nested"
      }
    }
  }
}

PUT test/_doc/1?refresh
{
  "title": "Test title",
  "comments": [
    {
      "author": "kimchy",
      "text": "comment text"
    },
    {
      "author": "nik9000",
      "text": "words words words"
    }
  ]
}

POST test/_search
{
  "query": {
    "nested": {
      "path": "comments",
      "query": {
        "match": {"comments.text" : "words"}
      },
      "inner_hits": {
        "_source" : false,
        "docvalue_fields" : [
          "comments.text.keyword"
        ]
      }
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1925.console"></div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="hierarchical-nested-inner-hits"></a>Hierarchical levels of nested object fields and inner hits.<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/inner-hits.asciidoc">edit</a>
</h4>
</div></div></div>
<p>If a mapping has multiple levels of hierarchical nested object fields each level can be accessed via dot notated path.
For example if there is a <code class="literal">comments</code> nested field that contains a <code class="literal">votes</code> nested field and votes should directly be returned
with the root hits then the following path can be defined:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT test
{
  "mappings": {
    "properties": {
      "comments": {
        "type": "nested",
        "properties": {
          "votes": {
            "type": "nested"
          }
        }
      }
    }
  }
}

PUT test/_doc/1?refresh
{
  "title": "Test title",
  "comments": [
    {
      "author": "kimchy",
      "text": "comment text",
      "votes": []
    },
    {
      "author": "nik9000",
      "text": "words words words",
      "votes": [
        {"value": 1 , "voter": "kimchy"},
        {"value": -1, "voter": "other"}
      ]
    }
  ]
}

POST test/_search
{
  "query": {
    "nested": {
      "path": "comments.votes",
        "query": {
          "match": {
            "comments.votes.voter": "kimchy"
          }
        },
        "inner_hits" : {}
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1926.console"></div>
<p>Which would look like:</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
  ...,
  "hits": {
    "total" : {
        "value": 1,
        "relation": "eq"
    },
    "max_score": 0.6931471,
    "hits": [
      {
        "_index": "test",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.6931471,
        "_source": ...,
        "inner_hits": {
          "comments.votes": { <a id="CO610-1"></a><i class="conum" data-value="1"></i>
            "hits": {
              "total" : {
                  "value": 1,
                  "relation": "eq"
              },
              "max_score": 0.6931471,
              "hits": [
                {
                  "_index": "test",
                  "_type": "_doc",
                  "_id": "1",
                  "_nested": {
                    "field": "comments",
                    "offset": 1,
                    "_nested": {
                      "field": "votes",
                      "offset": 0
                    }
                  },
                  "_score": 0.6931471,
                  "_source": {
                    "value": 1,
                    "voter": "kimchy"
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}</pre>
</div>
<p>This indirect referencing is only supported for nested inner hits.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="parent-child-inner-hits"></a>Parent/child inner hits<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/inner-hits.asciidoc">edit</a>
</h4>
</div></div></div>
<p>The parent/child <code class="literal">inner_hits</code> can be used to include parent or child:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT test
{
  "mappings": {
    "properties": {
      "my_join_field": {
        "type": "join",
        "relations": {
          "my_parent": "my_child"
        }
      }
    }
  }
}

PUT test/_doc/1?refresh
{
  "number": 1,
  "my_join_field": "my_parent"
}

PUT test/_doc/2?routing=1&amp;refresh
{
  "number": 1,
  "my_join_field": {
    "name": "my_child",
    "parent": "1"
  }
}

POST test/_search
{
  "query": {
    "has_child": {
      "type": "my_child",
      "query": {
        "match": {
          "number": 1
        }
      },
      "inner_hits": {}    <a id="CO610-2"></a><i class="conum" data-value="1"></i>
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1927.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO610-1"><i class="conum" data-value="1"></i></a><a href="#CO610-2"></a></p>
</td>
<td align="left" valign="top">
<p>The inner hit definition like in the nested example.</p>
</td>
</tr>
</table>
</div>
<p>An example of a response snippet that could be generated from the above search request:</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
    ...,
    "hits": {
        "total" : {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "test",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {
                    "number": 1,
                    "my_join_field": "my_parent"
                },
                "inner_hits": {
                    "my_child": {
                        "hits": {
                            "total" : {
                                "value": 1,
                                "relation": "eq"
                            },
                            "max_score": 1.0,
                            "hits": [
                                {
                                    "_index": "test",
                                    "_type": "_doc",
                                    "_id": "2",
                                    "_score": 1.0,
                                    "_routing": "1",
                                    "_source": {
                                        "number": 1,
                                        "my_join_field": {
                                            "name": "my_child",
                                            "parent": "1"
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        ]
    }
}</pre>
</div>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-min-score"></a>min_score<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/min-score.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Exclude documents which have a <code class="literal">_score</code> less than the minimum specified
in <code class="literal">min_score</code>:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "min_score": 0.5,
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1928.console"></div>
<p>Note, most times, this does not make much sense, but is provided for
advanced use cases.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-queries-and-filters"></a>Named Queries<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/named-queries-and-filters.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Each filter and query can accept a <code class="literal">_name</code> in its top level definition.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query": {
        "bool" : {
            "should" : [
                {"match" : { "name.first" : {"query" : "shay", "_name" : "first"} }},
                {"match" : { "name.last" : {"query" : "banon", "_name" : "last"} }}
            ],
            "filter" : {
                "terms" : {
                    "name.last" : ["banon", "kimchy"],
                    "_name" : "test"
                }
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1929.console"></div>
<p>The search response will include for each hit the <code class="literal">matched_queries</code> it matched on. The tagging of queries and filters
only make sense for the <code class="literal">bool</code> query.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-post-filter"></a>Post filter<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/post-filter.asciidoc">edit</a>
</h3>
</div></div></div>
<p>The <code class="literal">post_filter</code> is applied to the search <code class="literal">hits</code> at the very end of a search
request,  after aggregations have already been calculated. Its purpose is
best explained by example:</p>
<p>Imagine that you are selling shirts that have the following properties:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT /shirts
{
    "mappings": {
        "properties": {
            "brand": { "type": "keyword"},
            "color": { "type": "keyword"},
            "model": { "type": "keyword"}
        }
    }
}

PUT /shirts/_doc/1?refresh
{
    "brand": "gucci",
    "color": "red",
    "model": "slim"
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1930.console"></div>
<p>Imagine a user has specified two filters:</p>
<p><code class="literal">color:red</code> and <code class="literal">brand:gucci</code>.  You only want to show them red shirts made by
Gucci in the search results.  Normally you would do this with a
<a class="xref" href="query-dsl-bool-query.html" title="Boolean query"><code class="literal">bool</code> query</a>:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /shirts/_search
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "color": "red"   }},
        { "term": { "brand": "gucci" }}
      ]
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1931.console"></div>
<p>However, you would also like to use <em>faceted navigation</em> to display a list of
other options that the user could click on.  Perhaps you have a <code class="literal">model</code> field
that would allow the user to limit their search results to red Gucci
<code class="literal">t-shirts</code> or <code class="literal">dress-shirts</code>.</p>
<p>This can be done with a
<a class="xref" href="search-aggregations-bucket-terms-aggregation.html" title="Terms Aggregation"><code class="literal">terms</code> aggregation</a>:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /shirts/_search
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "color": "red"   }},
        { "term": { "brand": "gucci" }}
      ]
    }
  },
  "aggs": {
    "models": {
      "terms": { "field": "model" } <a id="CO611-1"></a><i class="conum" data-value="1"></i>
    }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1932.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO611-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>Returns the most popular models of red shirts by Gucci.</p>
</td>
</tr>
</table>
</div>
<p>But perhaps you would also like to tell the user how many Gucci shirts are
available in <span class="strong strong"><strong>other colors</strong></span>. If you just add a <code class="literal">terms</code> aggregation on the
<code class="literal">color</code> field, you will only get back the color <code class="literal">red</code>, because your query
returns only red shirts by Gucci.</p>
<p>Instead, you want to include shirts of all colors during aggregation, then
apply the <code class="literal">colors</code> filter only to the search results.  This is the purpose of
the <code class="literal">post_filter</code>:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /shirts/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": { "brand": "gucci" } <a id="CO612-1"></a><i class="conum" data-value="1"></i>
      }
    }
  },
  "aggs": {
    "colors": {
      "terms": { "field": "color" } <a id="CO612-2"></a><i class="conum" data-value="2"></i>
    },
    "color_red": {
      "filter": {
        "term": { "color": "red" } <a id="CO612-3"></a><i class="conum" data-value="3"></i>
      },
      "aggs": {
        "models": {
          "terms": { "field": "model" } <a id="CO612-4"></a><i class="conum" data-value="3"></i>
        }
      }
    }
  },
  "post_filter": { <a id="CO612-5"></a><i class="conum" data-value="4"></i>
    "term": { "color": "red" }
  }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1933.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO612-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>The main query now finds all shirts by Gucci, regardless of color.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO612-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>The <code class="literal">colors</code> agg returns popular colors for shirts by Gucci.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO612-3"><i class="conum" data-value="3"></i></a><a href="#CO612-4"></a></p>
</td>
<td align="left" valign="top">
<p>The <code class="literal">color_red</code> agg limits the <code class="literal">models</code> sub-aggregation
to <span class="strong strong"><strong>red</strong></span> Gucci shirts.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO612-5"><i class="conum" data-value="4"></i></a></p>
</td>
<td align="left" valign="top">
<p>Finally, the <code class="literal">post_filter</code> removes colors other than red
from the search <code class="literal">hits</code>.</p>
</td>
</tr>
</table>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-preference"></a>Preference<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/preference.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Controls a <code class="literal">preference</code> of the shard copies on which to execute the search.  By
default, Elasticsearch selects from the available shard copies in an
unspecified order, taking the <a class="xref" href="modules-cluster.html#shard-allocation-awareness" title="Shard allocation awareness">allocation awareness</a> and
<a class="xref" href="search.html#search-adaptive-replica" title="Adaptive Replica Selection">adaptive replica selection</a> configuration into
account. However, it may sometimes be desirable to try and route certain
searches to certain sets of shard copies.</p>
<p>A possible use case would be to make use of per-copy caches like the
<a class="xref" href="shard-request-cache.html" title="Shard request cache settings">request cache</a>. Doing this, however, runs contrary to the
idea of search parallelization and can create hotspots on certain nodes because
the load might not be evenly distributed anymore.</p>
<p>The <code class="literal">preference</code> is a query string parameter which can be set to:</p>
<div class="informaltable">
<table border="0" cellpadding="4px">
<colgroup>
<col>
<col>
</colgroup>
<tbody valign="top">
<tr>
<td valign="top">
<p>
<code class="literal">_only_local</code>
</p>
</td>
<td valign="top">
<p>
The operation will be executed only on shards allocated to the local
node.
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
<code class="literal">_local</code>
</p>
</td>
<td valign="top">
<p>
The operation will be executed on shards allocated to the local node if
possible, and will fall back to other shards if not.
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
<code class="literal">_prefer_nodes:abc,xyz</code>
</p>
</td>
<td valign="top">
<p>
The operation will be executed on nodes with one of the provided node
ids (<code class="literal">abc</code> or <code class="literal">xyz</code> in this case) if possible. If suitable shard copies
exist on more than one of the selected nodes then the order of
preference between these copies is unspecified.
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
<code class="literal">_shards:2,3</code>
</p>
</td>
<td valign="top">
<p>
Restricts the operation to the specified shards. (<code class="literal">2</code> and <code class="literal">3</code> in this
case).  This preference can be combined with other preferences but it
has to appear first: <code class="literal">_shards:2,3|_local</code>
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
<code class="literal">_only_nodes:abc*,x*yz,...</code>
</p>
</td>
<td valign="top">
<p>
Restricts the operation to nodes specified according to the
<a class="xref" href="cluster.html" title="Cluster APIs">node specification</a>. If suitable shard copies exist on more
than one of the selected nodes then the order of preference between
these copies is unspecified.
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
Custom (string) value
</p>
</td>
<td valign="top">
<p>
Any value that does not start with <code class="literal">_</code>. If two searches both give the same
custom string value for their preference and the underlying cluster state
does not change then the same ordering of shards will be used for the
searches. This does not guarantee that the exact same shards will be used
each time: the cluster state, and therefore the selected shards, may change
for a number of reasons including shard relocations and shard failures, and
nodes may sometimes reject searches causing fallbacks to alternative nodes.
However, in practice the ordering of shards tends to remain stable for long
periods of time. A good candidate for a custom preference value is something
like the web session id or the user name.
</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>For instance, use the user’s session ID <code class="literal">xyzabc123</code> as follows:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search?preference=xyzabc123
{
    "query": {
        "match": {
            "title": "elasticsearch"
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1934.console"></div>
<p>This can be an effective strategy to increase usage of e.g. the request cache for
unique users running similar searches repeatedly by always hitting the same cache, while
requests of different users are still spread across all shard copies.</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>The <code class="literal">_only_local</code> preference guarantees only to use shard copies on the
local node, which is sometimes useful for troubleshooting. All other options do
not <em>fully</em> guarantee that any particular shard copies are used in a search,
and on a changing index this may mean that repeated searches may yield
different results if they are executed on different shard copies which are in
different refresh states.</p>
</div>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-rescore"></a>Rescoring<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/rescore.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Rescoring can help to improve precision by reordering just the top (eg
100 - 500) documents returned by the
<a class="xref" href="search-search.html#request-body-search-query"><code class="literal">query</code></a> and
<a class="xref" href="search-request-body.html#request-body-search-post-filter" title="Post filter"><code class="literal">post_filter</code></a> phases, using a
secondary (usually more costly) algorithm, instead of applying the
costly algorithm to all documents in the index.</p>
<p>A <code class="literal">rescore</code> request is executed on each shard before it returns its
results to be sorted by the node handling the overall search request.</p>
<p>Currently the rescore API has only one implementation: the query
rescorer, which uses a query to tweak the scoring. In the future,
alternative rescorers may be made available, for example, a pair-wise rescorer.</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>An error will be thrown if an explicit <a class="xref" href="search-request-body.html#request-body-search-sort" title="Sort"><code class="literal">sort</code></a>
(other than <code class="literal">_score</code> in descending order) is provided with a <code class="literal">rescore</code> query.</p>
</div>
</div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>when exposing pagination to your users, you should not change
<code class="literal">window_size</code> as you step through each page (by passing different
<code class="literal">from</code> values) since that can alter the top hits causing results to
confusingly shift as the user steps through pages.</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_query_rescorer"></a>Query rescorer<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/rescore.asciidoc">edit</a>
</h4>
</div></div></div>
<p>The query rescorer executes a second query only on the Top-K results
returned by the <a class="xref" href="search-search.html#request-body-search-query"><code class="literal">query</code></a> and
<a class="xref" href="search-request-body.html#request-body-search-post-filter" title="Post filter"><code class="literal">post_filter</code></a> phases. The
number of docs which will be examined on each shard can be controlled by
the <code class="literal">window_size</code> parameter, which defaults to 10.</p>
<p>By default the scores from the original query and the rescore query are
combined linearly to produce the final <code class="literal">_score</code> for each document. The
relative importance of the original query and of the rescore query can
be controlled with the <code class="literal">query_weight</code> and <code class="literal">rescore_query_weight</code>
respectively. Both default to <code class="literal">1</code>.</p>
<p>For example:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /_search
{
   "query" : {
      "match" : {
         "message" : {
            "operator" : "or",
            "query" : "the quick brown"
         }
      }
   },
   "rescore" : {
      "window_size" : 50,
      "query" : {
         "rescore_query" : {
            "match_phrase" : {
               "message" : {
                  "query" : "the quick brown",
                  "slop" : 2
               }
            }
         },
         "query_weight" : 0.7,
         "rescore_query_weight" : 1.2
      }
   }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1935.console"></div>
<p>The way the scores are combined can be controlled with the <code class="literal">score_mode</code>:</p>
<div class="informaltable">
<table border="1" cellpadding="4px">
<colgroup>
<col class="col_1">
<col class="col_2">
</colgroup>
<thead>
<tr>
<th align="left" valign="top">Score Mode</th>
<th align="left" valign="top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p><code class="literal">total</code></p></td>
<td align="left" valign="top"><p>Add the original score and the rescore query score.  The default.</p></td>
</tr>
<tr>
<td align="left" valign="top"><p><code class="literal">multiply</code></p></td>
<td align="left" valign="top"><p>Multiply the original score by the rescore query score.  Useful
for <a class="xref" href="query-dsl-function-score-query.html" title="Function score query"><code class="literal">function query</code></a> rescores.</p></td>
</tr>
<tr>
<td align="left" valign="top"><p><code class="literal">avg</code></p></td>
<td align="left" valign="top"><p>Average the original score and the rescore query score.</p></td>
</tr>
<tr>
<td align="left" valign="top"><p><code class="literal">max</code></p></td>
<td align="left" valign="top"><p>Take the max of original score and the rescore query score.</p></td>
</tr>
<tr>
<td align="left" valign="top"><p><code class="literal">min</code></p></td>
<td align="left" valign="top"><p>Take the min of the original score and the rescore query score.</p></td>
</tr>
</tbody>
</table>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_multiple_rescores"></a>Multiple Rescores<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/rescore.asciidoc">edit</a>
</h4>
</div></div></div>
<p>It is also possible to execute multiple rescores in sequence:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /_search
{
   "query" : {
      "match" : {
         "message" : {
            "operator" : "or",
            "query" : "the quick brown"
         }
      }
   },
   "rescore" : [ {
      "window_size" : 100,
      "query" : {
         "rescore_query" : {
            "match_phrase" : {
               "message" : {
                  "query" : "the quick brown",
                  "slop" : 2
               }
            }
         },
         "query_weight" : 0.7,
         "rescore_query_weight" : 1.2
      }
   }, {
      "window_size" : 10,
      "query" : {
         "score_mode": "multiply",
         "rescore_query" : {
            "function_score" : {
               "script_score": {
                  "script": {
                    "source": "Math.log10(doc.likes.value + 2)"
                  }
               }
            }
         }
      }
   } ]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1936.console"></div>
<p>The first one gets the results of the query then the second one gets the
results of the first, etc.  The second rescore will "see" the sorting done
by the first rescore so it is possible to use a large window on the first
rescore to pull documents into a smaller window for the second rescore.</p>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-script-fields"></a>Script Fields<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/script-fields.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Allows to return a <a class="xref" href="modules-scripting.html" title="Scripting">script
evaluation</a> (based on different fields) for each hit, for example:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "match_all": {}
    },
    "script_fields" : {
        "test1" : {
            "script" : {
                "lang": "painless",
                "source": "doc['price'].value * 2"
            }
        },
        "test2" : {
            "script" : {
                "lang": "painless",
                "source": "doc['price'].value * params.factor",
                "params" : {
                    "factor"  : 2.0
                }
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1937.console"></div>
<p>Script fields can work on fields that are not stored (<code class="literal">price</code> in
the above case), and allow to return custom values to be returned (the
evaluated value of the script).</p>
<p>Script fields can also access the actual <code class="literal">_source</code> document and
extract specific elements to be returned from it by using <code class="literal">params['_source']</code>.
Here is an example:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
    {
        "query" : {
            "match_all": {}
        },
        "script_fields" : {
            "test1" : {
                "script" : "params['_source']['message']"
            }
        }
    }</pre>
</div>
<div class="console_widget" data-snippet="snippets/1938.console"></div>
<p>Note the <code class="literal">_source</code> keyword here to navigate the json-like model.</p>
<p>It’s important to understand the difference between
<code class="literal">doc['my_field'].value</code> and <code class="literal">params['_source']['my_field']</code>. The first,
using the doc keyword, will cause the terms for that field to be loaded to
memory (cached), which will result in faster execution, but more memory
consumption. Also, the <code class="literal">doc[...]</code> notation only allows for simple valued
fields (you can’t return a json object from it) and makes sense only for
non-analyzed or single term based fields. However, using <code class="literal">doc</code> is
still the recommended way to access values from the document, if at all
possible, because <code class="literal">_source</code> must be loaded and parsed every time it’s used.
Using <code class="literal">_source</code> is very slow.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-scroll"></a>Scroll<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/scroll.asciidoc">edit</a>
</h3>
</div></div></div>
<p>While a <code class="literal">search</code> request returns a single “page” of results, the <code class="literal">scroll</code>
API can be used to retrieve large numbers of results (or even all results)
from a single search request, in much the same way as you would use a cursor
on a traditional database.</p>
<p>Scrolling is not intended for real time user requests, but rather for
processing large amounts of data, e.g. in order to reindex the contents of one
index into a new index with a different configuration.</p>
<div class="sidebar">
<div class="titlepage"><div><div>
<p class="title"><strong>Client support for scrolling and reindexing</strong></p>
</div></div></div>
<p>Some of the officially supported clients provide helpers to assist with
scrolled searches and reindexing of documents from one index to another:</p>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
Perl
</span>
</dt>
<dd>
See <a href="https://metacpan.org/pod/Search::Elasticsearch::Client::5_0::Bulk" class="ulink" target="_top">Search::Elasticsearch::Client::5_0::Bulk</a>
and <a href="https://metacpan.org/pod/Search::Elasticsearch::Client::5_0::Scroll" class="ulink" target="_top">Search::Elasticsearch::Client::5_0::Scroll</a>
</dd>
<dt>
<span class="term">
Python
</span>
</dt>
<dd>
See <a href="http://elasticsearch-py.readthedocs.org/en/master/helpers.html" class="ulink" target="_top">elasticsearch.helpers.*</a>
</dd>
<dt>
<span class="term">
JavaScript
</span>
</dt>
<dd>
See <a href="/guide/en/elasticsearch/client/javascript-api/current/client-helpers.html" class="ulink" target="_top">client.helpers.*</a>
</dd>
</dl>
</div>
</div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>The results that are returned from a scroll request reflect the state of
the index at the time that the initial <code class="literal">search</code> request was  made, like a
snapshot in time. Subsequent changes to documents (index, update or delete)
will only affect later search requests.</p>
</div>
</div>
<p>In order to use scrolling, the initial search request should specify the
<code class="literal">scroll</code> parameter in the query string, which tells Elasticsearch how long it
should keep the “search context” alive (see <a class="xref" href="search-request-body.html#scroll-search-context" title="Keeping the search context alive">Keeping the search context alive</a>), eg <code class="literal">?scroll=1m</code>.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /twitter/_search?scroll=1m
{
    "size": 100,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1939.console"></div>
<p>The result from the above request includes a <code class="literal">_scroll_id</code>, which should
be passed to the <code class="literal">scroll</code> API in order to retrieve the next batch of
results.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /_search/scroll <a id="CO613-1"></a><i class="conum" data-value="1"></i>
{
    "scroll" : "1m", <a id="CO613-2"></a><i class="conum" data-value="2"></i>
    "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==" <a id="CO613-3"></a><i class="conum" data-value="3"></i>
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1940.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO613-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p><code class="literal">GET</code> or <code class="literal">POST</code> can be used and the URL should not include the <code class="literal">index</code>
name — this is specified in the original <code class="literal">search</code> request instead.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO613-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>The <code class="literal">scroll</code> parameter tells Elasticsearch to keep the search context open
for another <code class="literal">1m</code>.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO613-3"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>The <code class="literal">scroll_id</code> parameter</p>
</td>
</tr>
</table>
</div>
<p>The <code class="literal">size</code> parameter allows you to configure the maximum number of hits to be
returned with each batch of results.  Each call to the <code class="literal">scroll</code> API returns the
next batch of results until there are no more results left to return, ie the
<code class="literal">hits</code> array is empty.</p>
<div class="important admon">
<div class="icon"></div>
<div class="admon_content">
<p>The initial search request and each subsequent scroll request each
return a <code class="literal">_scroll_id</code>. While the <code class="literal">_scroll_id</code> may change between requests, it doesn’t
always change — in any case, only the most recently received <code class="literal">_scroll_id</code> should be used.</p>
</div>
</div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>If the request specifies aggregations, only the initial search response
will contain the aggregations results.</p>
</div>
</div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>Scroll requests have optimizations that make them faster when the sort
order is <code class="literal">_doc</code>. If you want to iterate over all documents regardless of the
order, this is the most efficient option:</p>
</div>
</div>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search?scroll=1m
{
  "sort": [
    "_doc"
  ]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1941.console"></div>
<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="scroll-search-context"></a>Keeping the search context alive<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/scroll.asciidoc">edit</a>
</h4>
</div></div></div>
<p>A scroll returns all the documents which matched the search at the time of the
initial search request. It ignores any subsequent changes to these documents.
The <code class="literal">scroll_id</code> identifies a <em>search context</em> which keeps track of everything
that Elasticsearch needs to return the correct documents. The search context is created
by the initial request and kept alive by subsequent requests.</p>
<p>The <code class="literal">scroll</code> parameter (passed to the <code class="literal">search</code> request and to every <code class="literal">scroll</code>
request) tells Elasticsearch how long it should keep the search context alive.
Its value (e.g. <code class="literal">1m</code>, see <a class="xref" href="common-options.html#time-units" title="Time units">Time units</a>) does not need to be long enough to
process all data — it just needs to be long enough to process the previous
batch of results. Each <code class="literal">scroll</code> request (with the <code class="literal">scroll</code> parameter) sets a
new  expiry time. If a <code class="literal">scroll</code> request doesn’t pass in the <code class="literal">scroll</code>
parameter, then the search context will be freed as part of <em>that</em> <code class="literal">scroll</code>
request.</p>
<p>Normally, the background merge process optimizes the index by merging together
smaller segments to create new, bigger segments. Once the smaller segments are
no longer needed they are deleted. This process continues during scrolling, but
an open search context prevents the old segments from being deleted since they
are still in use.</p>
<div class="tip admon">
<div class="icon"></div>
<div class="admon_content">
<p>Keeping older segments alive means that more disk space and file handles
are needed. Ensure that you have configured your nodes to have ample free file
handles. See <a class="xref" href="file-descriptors.html" title="File Descriptors">File Descriptors</a>.</p>
</div>
</div>
<p>Additionally, if a segment contains deleted or updated documents then the
search context must keep track of whether each document in the segment was live
at the time of the initial search request. Ensure that your nodes have
sufficient heap space if you have many open scrolls on an index that is subject
to ongoing deletes or updates.</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>To prevent against issues caused by having too many scrolls open, the
user is not allowed to open scrolls past a certain limit. By default, the
maximum number of open scrolls is 500. This limit can be updated with the
<code class="literal">search.max_open_scroll_context</code> cluster setting.</p>
</div>
</div>
<p>You can check how many search contexts are open with the
<a class="xref" href="cluster-nodes-stats.html" title="Nodes stats API">nodes stats API</a>:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_nodes/stats/indices/search</pre>
</div>
<div class="console_widget" data-snippet="snippets/1942.console"></div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_clear_scroll_api"></a>Clear scroll API<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/scroll.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Search context are automatically removed when the <code class="literal">scroll</code> timeout has been
exceeded. However keeping scrolls open has a cost, as discussed in the
<a class="xref" href="search-request-body.html#scroll-search-context" title="Keeping the search context alive">previous section</a> so scrolls should be explicitly
cleared as soon as the scroll is not being used anymore using the
<code class="literal">clear-scroll</code> API:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">DELETE /_search/scroll
{
    "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1943.console"></div>
<p>Multiple scroll IDs can be passed as array:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">DELETE /_search/scroll
{
    "scroll_id" : [
      "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==",
      "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAABFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAAAxZrUllkUVlCa1NqNmRMaUhiQlZkMWFBAAAAAAAAAAIWa1JZZFFZQmtTajZkTGlIYkJWZDFhQQAAAAAAAAAFFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAABBZrUllkUVlCa1NqNmRMaUhiQlZkMWFB"
    ]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1944.console"></div>
<p>All search contexts can be cleared with the <code class="literal">_all</code> parameter:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">DELETE /_search/scroll/_all</pre>
</div>
<div class="console_widget" data-snippet="snippets/1945.console"></div>
<p>The <code class="literal">scroll_id</code> can also be passed as a query string parameter or in the request body.
Multiple scroll IDs can be passed as comma separated values:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">DELETE /_search/scroll/DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==,DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAABFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAAAxZrUllkUVlCa1NqNmRMaUhiQlZkMWFBAAAAAAAAAAIWa1JZZFFZQmtTajZkTGlIYkJWZDFhQQAAAAAAAAAFFmtSWWRRWUJrU2o2ZExpSGJCVmQxYUEAAAAAAAAABBZrUllkUVlCa1NqNmRMaUhiQlZkMWFB</pre>
</div>
<div class="console_widget" data-snippet="snippets/1946.console"></div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="sliced-scroll"></a>Sliced Scroll<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/scroll.asciidoc">edit</a>
</h4>
</div></div></div>
<p>For scroll queries that return a lot of documents it is possible to split the scroll in multiple slices which
can be consumed independently:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /twitter/_search?scroll=1m
{
    "slice": {
        "id": 0, <a id="CO614-1"></a><i class="conum" data-value="1"></i>
        "max": 2 <a id="CO614-2"></a><i class="conum" data-value="2"></i>
    },
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    }
}
GET /twitter/_search?scroll=1m
{
    "slice": {
        "id": 1,
        "max": 2
    },
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1947.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO614-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>The id of the slice</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO614-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>The maximum number of slices</p>
</td>
</tr>
</table>
</div>
<p>The result from the first request returned documents that belong to the first slice (id: 0) and the result from the
second request returned documents that belong to the second slice. Since the maximum number of slices is set to 2
 the union of the results of the two requests is equivalent to the results of a scroll query without slicing.
By default the splitting is done on the shards first and then locally on each shard using the _id field
with the following formula:
<code class="literal">slice(doc) = floorMod(hashCode(doc._id), max)</code>
For instance if the number of shards is equal to 2 and the user requested 4 slices then the slices 0 and 2 are assigned
to the first shard and the slices 1 and 3 are assigned to the second shard.</p>
<p>Each scroll is independent and can be processed in parallel like any scroll request.</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>If the number of slices is bigger than the number of shards the slice filter is very slow on the first calls, it has a complexity of O(N) and a memory cost equals
to N bits per slice where N is the total number of documents in the shard.
After few calls the filter should be cached and subsequent calls should be faster but you should limit the number of
 sliced query you perform in parallel to avoid the memory explosion.</p>
</div>
</div>
<p>To avoid this cost entirely it is possible to use the <code class="literal">doc_values</code> of another field to do the slicing
but the user must ensure that the field has the following properties:</p>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
The field is numeric.
</li>
<li class="listitem">
<code class="literal">doc_values</code> are enabled on that field
</li>
<li class="listitem">
Every document should contain a single value. If a document has multiple values for the specified field, the first value is used.
</li>
<li class="listitem">
The value for each document should be set once when the document is created and never updated. This ensures that each
slice gets deterministic results.
</li>
<li class="listitem">
The cardinality of the field should be high. This ensures that each slice gets approximately the same amount of documents.
</li>
</ul>
</div>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /twitter/_search?scroll=1m
{
    "slice": {
        "field": "date",
        "id": 0,
        "max": 10
    },
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1948.console"></div>
<p>For append only time-based indices, the <code class="literal">timestamp</code> field can be used safely.</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>By default the maximum number of slices allowed per scroll is limited to 1024.
You can update the <code class="literal">index.max_slices_per_scroll</code> index setting to bypass this limit.</p>
</div>
</div>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-search-after"></a>Search After<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/search-after.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Pagination of results can be done by using the <code class="literal">from</code> and <code class="literal">size</code> but the cost becomes prohibitive when the deep pagination is reached.
The <code class="literal">index.max_result_window</code> which defaults to 10,000 is a safeguard, search requests take heap memory and time proportional to <code class="literal">from + size</code>.
The <a class="xref" href="search-request-body.html#request-body-search-scroll" title="Scroll">Scroll</a> api is recommended for efficient deep scrolling but scroll contexts are costly and it is not
recommended to use it for real time user requests.
The <code class="literal">search_after</code> parameter circumvents this problem by providing a live cursor.
The idea is to use the results from the previous page to help the retrieval of the next page.</p>
<p>Suppose that the query to retrieve the first page looks like this:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET twitter/_search
{
    "size": 10,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    },
    "sort": [
        {"date": "asc"},
        {"tie_breaker_id": "asc"}      <a id="CO615-1"></a><i class="conum" data-value="1"></i>
    ]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1949.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO615-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>A copy of the <code class="literal">_id</code> field with <code class="literal">doc_values</code> enabled</p>
</td>
</tr>
</table>
</div>
<div class="important admon">
<div class="icon"></div>
<div class="admon_content">
<p>A field with one unique value per document should be used as the tiebreaker
of the sort specification. Otherwise the sort order for documents that have
the same sort values would be undefined and could lead to missing or duplicate
results. The <a class="xref" href="mapping-id-field.html" title="_id field"><code class="literal">_id</code> field</a> has a unique value per document
but it is not recommended to use it as a tiebreaker directly.
Beware that <code class="literal">search_after</code> looks for the first document which fully or partially
matches tiebreaker’s provided value. Therefore if a document has a tiebreaker value of
<code class="literal">"654323"</code> and you <code class="literal">search_after</code> for <code class="literal">"654"</code> it would still match that document
and return results found after it.
<a class="xref" href="doc-values.html" title="doc_values">doc value</a> are disabled on this field so sorting on it requires
to load a lot of data in memory. Instead it is advised to duplicate (client side
 or with a <a class="xref" href="ingest-processors.html" title="Processors">set ingest processor</a>) the content
of the <a class="xref" href="mapping-id-field.html" title="_id field"><code class="literal">_id</code> field</a> in another field that has
<a class="xref" href="doc-values.html" title="doc_values">doc value</a> enabled and to use this new field as the tiebreaker
for the sort.</p>
</div>
</div>
<p>The result from the above request includes an array of <code class="literal">sort values</code> for each document.
These <code class="literal">sort values</code> can be used in conjunction with the <code class="literal">search_after</code> parameter to start returning results "after" any
document in the result list.
For instance we can use the <code class="literal">sort values</code> of the last document and pass it to <code class="literal">search_after</code> to retrieve the next page of results:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET twitter/_search
{
    "size": 10,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    },
    "search_after": [1463538857, "654323"],
    "sort": [
        {"date": "asc"},
        {"tie_breaker_id": "asc"}
    ]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1950.console"></div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>The parameter <code class="literal">from</code> must be set to 0 (or -1) when <code class="literal">search_after</code> is used.</p>
</div>
</div>
<p><code class="literal">search_after</code> is not a solution to jump freely to a random page but rather to scroll many queries in parallel.
It is very similar to the <code class="literal">scroll</code> API but unlike it, the <code class="literal">search_after</code> parameter is stateless, it is always resolved against the latest
 version of the searcher. For this reason the sort order may change during a walk depending on the updates and deletes of your index.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-search-type"></a>Search Type<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/search-type.asciidoc">edit</a>
</h3>
</div></div></div>
<p>There are different execution paths that can be done when executing a
distributed search. The distributed search operation needs to be
scattered to all the relevant shards and then all the results are
gathered back. When doing scatter/gather type execution, there are
several ways to do that, specifically with search engines.</p>
<p>One of the questions when executing a distributed search is how many
results to retrieve from each shard. For example, if we have 10 shards,
the 1st shard might hold the most relevant results from 0 till 10, with
other shards results ranking below it. For this reason, when executing a
request, we will need to get results from 0 till 10 from all shards,
sort them, and then return the results if we want to ensure correct
results.</p>
<p>Another question, which relates to the search engine, is the fact that each
shard stands on its own. When a query is executed on a specific shard,
it does not take into account term frequencies and other search engine
information from the other shards. If we want to support accurate
ranking, we would need to first gather the term frequencies from all
shards to calculate global term frequencies, then execute the query on
each shard using these global frequencies.</p>
<p>Also, because of the need to sort the results, getting back a large
document set, or even scrolling it, while maintaining the correct sorting
behavior can be a very expensive operation. For large result set
scrolling, it is best to sort by <code class="literal">_doc</code> if the order in which documents
are returned is not important.</p>
<p>Elasticsearch is very flexible and allows to control the type of search
to execute on a <span class="strong strong"><strong>per search request</strong></span> basis. The type can be configured
by setting the <span class="strong strong"><strong>search_type</strong></span> parameter in the query string. The types
are:</p>
<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="query-then-fetch"></a>Query Then Fetch<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/search-type.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Parameter value: <span class="strong strong"><strong>query_then_fetch</strong></span>.</p>
<p>The request is processed in two phases. In the first phase, the query
is forwarded to <span class="strong strong"><strong>all involved shards</strong></span>. Each shard executes the search
and generates a sorted list of results, local to that shard. Each
shard returns <span class="strong strong"><strong>just enough information</strong></span> to the coordinating node
to allow it to merge and re-sort the shard level results into a globally
sorted set of results, of maximum length <code class="literal">size</code>.</p>
<p>During the second phase, the coordinating node requests the document
content (and highlighted snippets, if any) from <span class="strong strong"><strong>only the relevant
shards</strong></span>.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET twitter/_search?search_type=query_then_fetch</pre>
</div>
<div class="console_widget" data-snippet="snippets/1951.console"></div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>This is the default setting, if you do not specify a <code class="literal">search_type</code>
      in your request.</p>
</div>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="dfs-query-then-fetch"></a>Dfs, Query Then Fetch<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/search-type.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Parameter value: <span class="strong strong"><strong>dfs_query_then_fetch</strong></span>.</p>
<p>Same as "Query Then Fetch", except for an initial scatter phase which
goes and computes the distributed term frequencies for more accurate
scoring.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET twitter/_search?search_type=dfs_query_then_fetch</pre>
</div>
<div class="console_widget" data-snippet="snippets/1952.console"></div>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-sort"></a>Sort<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Allows you to add one or more sorts on specific fields. Each sort can be
reversed as well. The sort is defined on a per field level, with special
field name for <code class="literal">_score</code> to sort by score, and <code class="literal">_doc</code> to sort by index order.</p>
<p>Assuming the following index mapping:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT /my_index
{
    "mappings": {
        "properties": {
            "post_date": { "type": "date" },
            "user": {
                "type": "keyword"
            },
            "name": {
                "type": "keyword"
            },
            "age": { "type": "integer" }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1953.console"></div>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /my_index/_search
{
    "sort" : [
        { "post_date" : {"order" : "asc"}},
        "user",
        { "name" : "desc" },
        { "age" : "desc" },
        "_score"
    ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1954.console"></div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p><code class="literal">_doc</code> has no real use-case besides being the most efficient sort order.
So if you don’t care about the order in which documents are returned, then you
should sort by <code class="literal">_doc</code>. This especially helps when <a class="xref" href="search-request-body.html#request-body-search-scroll" title="Scroll">scrolling</a>.</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_sort_values"></a>Sort Values<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h4>
</div></div></div>
<p>The sort values for each document returned are also returned as part of
the response.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_sort_order"></a>Sort Order<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h4>
</div></div></div>
<p>The <code class="literal">order</code> option can have the following values:</p>
<div class="informaltable">
<table border="0" cellpadding="4px">
<colgroup>
<col>
<col>
</colgroup>
<tbody valign="top">
<tr>
<td valign="top">
<p>
<code class="literal">asc</code>
</p>
</td>
<td valign="top">
<p>
Sort in ascending order
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
<code class="literal">desc</code>
</p>
</td>
<td valign="top">
<p>
Sort in descending order
</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>The order defaults to <code class="literal">desc</code> when sorting on the <code class="literal">_score</code>, and defaults
to <code class="literal">asc</code> when sorting on anything else.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_sort_mode_option"></a>Sort mode option<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Elasticsearch supports sorting by array or multi-valued fields. The <code class="literal">mode</code> option
controls what array value is picked for sorting the document it belongs
to. The <code class="literal">mode</code> option can have the following values:</p>
<div class="informaltable">
<table border="0" cellpadding="4px">
<colgroup>
<col>
<col>
</colgroup>
<tbody valign="top">
<tr>
<td valign="top">
<p>
<code class="literal">min</code>
</p>
</td>
<td valign="top">
<p>
Pick the lowest value.
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
<code class="literal">max</code>
</p>
</td>
<td valign="top">
<p>
Pick the highest value.
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
<code class="literal">sum</code>
</p>
</td>
<td valign="top">
<p>
Use the sum of all values as sort value. Only applicable for
number based array fields.
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
<code class="literal">avg</code>
</p>
</td>
<td valign="top">
<p>
Use the average of all values as sort value. Only applicable
for number based array fields.
</p>
</td>
</tr>
<tr>
<td valign="top">
<p>
<code class="literal">median</code>
</p>
</td>
<td valign="top">
<p>
Use the median of all values as sort value.  Only applicable
for number based array fields.
</p>
</td>
</tr>
</tbody>
</table>
</div>
<p>The default sort mode in the ascending sort order is <code class="literal">min</code> — the lowest value
is picked. The default sort mode in the descending order is <code class="literal">max</code> — the highest value is picked.</p>
<div class="section">
<div class="titlepage"><div><div>
<h5 class="title">
<a id="_sort_mode_example_usage"></a>Sort mode example usage<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h5>
</div></div></div>
<p>In the example below the field price has multiple prices per document.
In this case the result hits will be sorted by price ascending based on
the average price per document.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT /my_index/_doc/1?refresh
{
   "product": "chocolate",
   "price": [20, 4]
}

POST /_search
{
   "query" : {
      "term" : { "product" : "chocolate" }
   },
   "sort" : [
      {"price" : {"order" : "asc", "mode" : "avg"}}
   ]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1955.console"></div>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_sorting_numeric_fields"></a>Sorting numeric fields<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h4>
</div></div></div>
<p>For numeric fields it is also possible to cast the values from one type
to another using the <code class="literal">numeric_type</code> option.
This option accepts the following values: [<code class="literal">"double", "long", "date", "date_nanos"</code>]
and can be useful for cross-index search if the sort field is mapped differently on some
indices.</p>
<p>Consider for instance these two indices:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT /index_double
{
    "mappings": {
        "properties": {
            "field": { "type": "double" }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1956.console"></div>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT /index_long
{
    "mappings": {
        "properties": {
            "field": { "type": "long" }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1957.console"></div>
<p>Since <code class="literal">field</code> is mapped as a <code class="literal">double</code> in the first index and as a <code class="literal">long</code>
in the second index, it is not possible to use this field to sort requests
that query both indices by default. However you can force the type to one
or the other with the <code class="literal">numeric_type</code> option in order to force a specific
type for all indices:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /index_long,index_double/_search
{
   "sort" : [
      {
        "field" : {
            "numeric_type" : "double"
        }
      }
   ]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1958.console"></div>
<p>In the example above, values for the <code class="literal">index_long</code> index are casted to
a double in order to be compatible with the values produced by the
<code class="literal">index_double</code> index.
It is also possible to transform a floating point field into a <code class="literal">long</code>
but note that in this case floating points are replaced by the largest
value that is less than or equal (greater than or equal if the value
is negative) to the argument and is equal to a mathematical integer.</p>
<p>This option can also be used to convert a <code class="literal">date</code> field that uses millisecond
resolution to a <code class="literal">date_nanos</code> field with nanosecond resolution.
Consider for instance these two indices:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT /index_double
{
    "mappings": {
        "properties": {
            "field": { "type": "date" }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1959.console"></div>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">PUT /index_long
{
    "mappings": {
        "properties": {
            "field": { "type": "date_nanos" }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1960.console"></div>
<p>Values in these indices are stored with different resolutions so sorting on these
fields will always sort the <code class="literal">date</code> before the <code class="literal">date_nanos</code> (ascending order).
With the <code class="literal">numeric_type</code> type option it is possible to set a single resolution for
the sort, setting to <code class="literal">date</code> will convert the <code class="literal">date_nanos</code> to the millisecond resolution
while <code class="literal">date_nanos</code> will convert the values in the <code class="literal">date</code> field to the nanoseconds resolution:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /index_long,index_double/_search
{
   "sort" : [
      {
        "field" : {
            "numeric_type" : "date_nanos"
        }
      }
   ]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1961.console"></div>
<div class="warning admon">
<div class="icon"></div>
<div class="admon_content">
<p>To avoid overflow, the conversion to <code class="literal">date_nanos</code> cannot be applied on dates before
1970 and after 2262 as nanoseconds are represented as longs.</p>
</div>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="nested-sorting"></a>Sorting within nested objects.<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Elasticsearch also supports sorting by
fields that are inside one or more nested objects. The sorting by nested
field support has a <code class="literal">nested</code> sort option with the following properties:</p>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
<code class="literal">path</code>
</span>
</dt>
<dd>
Defines on which nested object to sort. The actual
sort field must be a direct field inside this nested object.
When sorting by nested field, this field is mandatory.
</dd>
<dt>
<span class="term">
<code class="literal">filter</code>
</span>
</dt>
<dd>
A filter that the inner objects inside the nested path
should match with in order for its field values to be taken into account
by sorting. Common case is to repeat the query / filter inside the
nested filter or query. By default no <code class="literal">nested_filter</code> is active.
</dd>
<dt>
<span class="term">
<code class="literal">max_children</code>
</span>
</dt>
<dd>
The maximum number of children to consider per root document
when picking the sort value. Defaults to unlimited.
</dd>
<dt>
<span class="term">
<code class="literal">nested</code>
</span>
</dt>
<dd>
Same as top-level <code class="literal">nested</code> but applies to another nested path within the
current nested object.
</dd>
</dl>
</div>
<div class="warning admon">
<div class="icon"></div>
<div class="admon_content">
<h3>Nested sort options before Elasticsearch 6.1</h3>
<p>The <code class="literal">nested_path</code> and <code class="literal">nested_filter</code> options have been deprecated in
favor of the options documented above.</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h5 class="title">
<a id="_nested_sorting_examples"></a>Nested sorting examples<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h5>
</div></div></div>
<p>In the below example <code class="literal">offer</code> is a field of type <code class="literal">nested</code>.
The nested <code class="literal">path</code> needs to be specified; otherwise, Elasticsearch doesn’t know on what nested level sort values need to be captured.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /_search
{
   "query" : {
      "term" : { "product" : "chocolate" }
   },
   "sort" : [
       {
          "offer.price" : {
             "mode" :  "avg",
             "order" : "asc",
             "nested": {
                "path": "offer",
                "filter": {
                   "term" : { "offer.color" : "blue" }
                }
             }
          }
       }
    ]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1962.console"></div>
<p>In the below example <code class="literal">parent</code> and <code class="literal">child</code> fields are of type <code class="literal">nested</code>.
The <code class="literal">nested_path</code> needs to be specified at each level; otherwise, Elasticsearch doesn’t know on what nested level sort values need to be captured.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /_search
{
   "query": {
      "nested": {
         "path": "parent",
         "query": {
            "bool": {
                "must": {"range": {"parent.age": {"gte": 21}}},
                "filter": {
                    "nested": {
                        "path": "parent.child",
                        "query": {"match": {"parent.child.name": "matt"}}
                    }
                }
            }
         }
      }
   },
   "sort" : [
      {
         "parent.child.age" : {
            "mode" :  "min",
            "order" : "asc",
            "nested": {
               "path": "parent",
               "filter": {
                  "range": {"parent.age": {"gte": 21}}
               },
               "nested": {
                  "path": "parent.child",
                  "filter": {
                     "match": {"parent.child.name": "matt"}
                  }
               }
            }
         }
      }
   ]
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1963.console"></div>
<p>Nested sorting is also supported when sorting by
scripts and sorting by geo distance.</p>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_missing_values_4"></a>Missing Values<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h4>
</div></div></div>
<p>The <code class="literal">missing</code> parameter specifies how docs which are missing
the sort field should be treated: The <code class="literal">missing</code> value can be
set to <code class="literal">_last</code>, <code class="literal">_first</code>, or a custom value (that
will be used for missing docs as the sort value).
The default is <code class="literal">_last</code>.</p>
<p>For example:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "sort" : [
        { "price" : {"missing" : "_last"} }
    ],
    "query" : {
        "term" : { "product" : "chocolate" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1964.console"></div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>If a nested inner object doesn’t match with
the <code class="literal">nested_filter</code> then a missing value is used.</p>
</div>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_ignoring_unmapped_fields"></a>Ignoring Unmapped Fields<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h4>
</div></div></div>
<p>By default, the search request will fail if there is no mapping
associated with a field. The <code class="literal">unmapped_type</code> option allows you to ignore
fields that have no mapping and not sort by them. The value of this
parameter is used to determine what sort values to emit. Here is an
example of how it can be used:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "sort" : [
        { "price" : {"unmapped_type" : "long"} }
    ],
    "query" : {
        "term" : { "product" : "chocolate" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1965.console"></div>
<p>If any of the indices that are queried doesn’t have a mapping for <code class="literal">price</code>
then Elasticsearch will handle it as if there was a mapping of type
<code class="literal">long</code>, with all documents in this index having no value for this field.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="geo-sorting"></a>Geo Distance Sorting<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Allow to sort by <code class="literal">_geo_distance</code>. Here is an example, assuming <code class="literal">pin.location</code> is a field of type <code class="literal">geo_point</code>:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "sort" : [
        {
            "_geo_distance" : {
                "pin.location" : [-70, 40],
                "order" : "asc",
                "unit" : "km",
                "mode" : "min",
                "distance_type" : "arc",
                "ignore_unmapped": true
            }
        }
    ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1966.console"></div>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
<code class="literal">distance_type</code>
</span>
</dt>
<dd>
How to compute the distance. Can either be <code class="literal">arc</code> (default), or <code class="literal">plane</code> (faster, but inaccurate on long distances and close to the poles).
</dd>
<dt>
<span class="term">
<code class="literal">mode</code>
</span>
</dt>
<dd>
What to do in case a field has several geo points. By default, the shortest
distance is taken into account when sorting in ascending order and the
longest distance when sorting in descending order. Supported values are
<code class="literal">min</code>, <code class="literal">max</code>, <code class="literal">median</code> and <code class="literal">avg</code>.
</dd>
<dt>
<span class="term">
<code class="literal">unit</code>
</span>
</dt>
<dd>
The unit to use when computing sort values. The default is <code class="literal">m</code> (meters).
</dd>
<dt>
<span class="term">
<code class="literal">ignore_unmapped</code>
</span>
</dt>
<dd>
Indicates if the unmapped field should be treated as a missing value. Setting it to <code class="literal">true</code> is equivalent to specifying
an <code class="literal">unmapped_type</code> in the field sort. The default is <code class="literal">false</code> (unmapped field cause the search to fail).
</dd>
</dl>
</div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>geo distance sorting does not support configurable missing values: the
distance will always be considered equal to <code class="literal">Infinity</code> when a document does not
have values for the field that is used for distance computation.</p>
</div>
</div>
<p>The following formats are supported in providing the coordinates:</p>
<div class="section">
<div class="titlepage"><div><div>
<h5 class="title">
<a id="_lat_lon_as_properties_3"></a>Lat Lon as Properties<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h5>
</div></div></div>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "sort" : [
        {
            "_geo_distance" : {
                "pin.location" : {
                    "lat" : 40,
                    "lon" : -70
                },
                "order" : "asc",
                "unit" : "km"
            }
        }
    ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1967.console"></div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h5 class="title">
<a id="_lat_lon_as_string_4"></a>Lat Lon as String<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h5>
</div></div></div>
<p>Format in <code class="literal">lat,lon</code>.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "sort" : [
        {
            "_geo_distance" : {
                "pin.location" : "40,-70",
                "order" : "asc",
                "unit" : "km"
            }
        }
    ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1968.console"></div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h5 class="title">
<a id="_geohash_4"></a>Geohash<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h5>
</div></div></div>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "sort" : [
        {
            "_geo_distance" : {
                "pin.location" : "drm3btev3e86",
                "order" : "asc",
                "unit" : "km"
            }
        }
    ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1969.console"></div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h5 class="title">
<a id="_lat_lon_as_array_3"></a>Lat Lon as Array<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h5>
</div></div></div>
<p>Format in <code class="literal">[lon, lat]</code>, note, the order of lon/lat here in order to
conform with <a href="http://geojson.org/" class="ulink" target="_top">GeoJSON</a>.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "sort" : [
        {
            "_geo_distance" : {
                "pin.location" : [-70, 40],
                "order" : "asc",
                "unit" : "km"
            }
        }
    ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1970.console"></div>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_multiple_reference_points"></a>Multiple reference points<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Multiple geo points can be passed as an array containing any <code class="literal">geo_point</code> format, for example</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "sort" : [
        {
            "_geo_distance" : {
                "pin.location" : [[-70, 40], [-71, 42]],
                "order" : "asc",
                "unit" : "km"
            }
        }
    ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1971.console"></div>
<p>and so forth.</p>
<p>The final distance for a document will then be <code class="literal">min</code>/<code class="literal">max</code>/<code class="literal">avg</code> (defined via <code class="literal">mode</code>) distance of all points contained in the document to all points given in the sort request.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_script_based_sorting"></a>Script Based Sorting<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h4>
</div></div></div>
<p>Allow to sort based on custom scripts, here is an example:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "query" : {
        "term" : { "user" : "kimchy" }
    },
    "sort" : {
        "_script" : {
            "type" : "number",
            "script" : {
                "lang": "painless",
                "source": "doc['field_name'].value * params.factor",
                "params" : {
                    "factor" : 1.1
                }
            },
            "order" : "asc"
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1972.console"></div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_track_scores"></a>Track Scores<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h4>
</div></div></div>
<p>When sorting on a field, scores are not computed. By setting
<code class="literal">track_scores</code> to true, scores will still be computed and tracked.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "track_scores": true,
    "sort" : [
        { "post_date" : {"order" : "desc"} },
        { "name" : "desc" },
        { "age" : "desc" }
    ],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1973.console"></div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_memory_considerations"></a>Memory Considerations<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/sort.asciidoc">edit</a>
</h4>
</div></div></div>
<p>When sorting, the relevant sorted field values are loaded into memory.
This means that per shard, there should be enough memory to contain
them. For string based types, the field sorted on should not be analyzed
/ tokenized. For numeric types, if possible, it is recommended to
explicitly set the type to narrower types (like <code class="literal">short</code>, <code class="literal">integer</code> and
<code class="literal">float</code>).</p>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-source-filtering"></a>Source filtering<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/source-filtering.asciidoc">edit</a>
</h3>
</div></div></div>
<p>See <a class="xref" href="run-a-search.html#source-filtering" title="Source filtering">source filtering</a>.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-stored-fields"></a>Stored Fields<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/stored-fields.asciidoc">edit</a>
</h3>
</div></div></div>
<div class="warning admon">
<div class="icon"></div>
<div class="admon_content">
<p>The <code class="literal">stored_fields</code> parameter is about fields that are explicitly marked as
stored in the mapping, which is off by default and generally not recommended.
Use <a class="xref" href="run-a-search.html#source-filtering" title="Source filtering">source filtering</a> instead to select
subsets of the original source document to be returned.</p>
</div>
</div>
<p>Allows to selectively load specific stored fields for each document represented
by a search hit.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "stored_fields" : ["user", "postDate"],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1974.console"></div>
<p><code class="literal">*</code> can be used to load all stored fields from the document.</p>
<p>An empty array will cause only the <code class="literal">_id</code> and <code class="literal">_type</code> for each hit to be
returned, for example:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "stored_fields" : [],
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1975.console"></div>
<p>If the requested fields are not stored (<code class="literal">store</code> mapping set to <code class="literal">false</code>), they will be ignored.</p>
<p>Stored field values fetched from the document itself are always returned as an array. On the contrary, metadata fields like <code class="literal">_routing</code> are never returned as an array.</p>
<p>Also only leaf fields can be returned via the <code class="literal">stored_fields</code> option. If an object field is specified, it will be ignored.</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>On its own, <code class="literal">stored_fields</code> cannot be used to load fields in nested
objects — if a field contains a nested object in its path, then no data will
be returned for that stored field. To access nested fields, <code class="literal">stored_fields</code>
must be used within an <a class="xref" href="search-request-body.html#request-body-search-inner-hits" title="Inner hits"><code class="literal">inner_hits</code></a> block.</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h4 class="title">
<a id="_disable_stored_fields_entirely"></a>Disable stored fields entirely<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/stored-fields.asciidoc">edit</a>
</h4>
</div></div></div>
<p>To disable the stored fields (and metadata fields) entirely use: <code class="literal">_none_</code>:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET /_search
{
    "stored_fields": "_none_",
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1976.console"></div>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p><a class="xref" href="run-a-search.html#source-filtering" title="Source filtering"><code class="literal">_source</code></a> and <a class="xref" href="search-search.html#request-body-search-version"><code class="literal">version</code></a> parameters cannot be activated if <code class="literal">_none_</code> is used.</p>
</div>
</div>
</div>

</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="request-body-search-track-total-hits"></a>Track total hits<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/search/request/track-total-hits.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Generally the total hit count can’t be computed accurately without visiting all
matches, which is costly for queries that match lots of documents. The
<code class="literal">track_total_hits</code> parameter allows you to control how the total number of hits
should be tracked.
Given that it is often enough to have a lower bound of the number of hits,
such as "there are at least 10000 hits", the default is set to <code class="literal">10,000</code>.
This means that requests will count the total hit accurately up to <code class="literal">10,000</code> hits.
It’s is a good trade off to speed up searches if you don’t need the accurate number
of hits after a certain threshold.</p>
<p>When set to <code class="literal">true</code> the search response will always track the number of hits that
match the query accurately (e.g. <code class="literal">total.relation</code> will always be equal to <code class="literal">"eq"</code>
when <code class="literal">track_total_hits</code> is set to true). Otherwise the <code class="literal">"total.relation"</code> returned
in the <code class="literal">"total"</code> object in the search response determines how the <code class="literal">"total.value"</code>
should be interpreted. A value of <code class="literal">"gte"</code> means that the <code class="literal">"total.value"</code> is a
lower bound of the total hits that match the query and a value of <code class="literal">"eq"</code> indicates
that <code class="literal">"total.value"</code> is the accurate count.</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET twitter/_search
{
    "track_total_hits": true,
     "query": {
        "match" : {
            "message" : "Elasticsearch"
        }
     }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1977.console"></div>
<p>... returns:</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
    "_shards": ...
    "timed_out": false,
    "took": 100,
    "hits": {
        "max_score": 1.0,
        "total" : {
            "value": 2048,    <a id="CO616-1"></a><i class="conum" data-value="1"></i>
            "relation": "eq"  <a id="CO616-2"></a><i class="conum" data-value="2"></i>
        },
        "hits": ...
    }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO616-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>The total number of hits that match the query.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO616-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>The count is accurate (e.g. <code class="literal">"eq"</code> means equals).</p>
</td>
</tr>
</table>
</div>
<p>It is also possible to set <code class="literal">track_total_hits</code> to an integer.
For instance the following query will accurately track the total hit count that match
the query up to 100 documents:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET twitter/_search
{
    "track_total_hits": 100,
     "query": {
        "match" : {
            "message" : "Elasticsearch"
        }
     }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1978.console"></div>
<p>The <code class="literal">hits.total.relation</code> in the response will indicate if the
value returned in <code class="literal">hits.total.value</code> is accurate (<code class="literal">"eq"</code>) or a lower
bound of the total (<code class="literal">"gte"</code>).</p>
<p>For instance the following response:</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
    "_shards": ...
    "timed_out": false,
    "took": 30,
    "hits" : {
        "max_score": 1.0,
        "total" : {
            "value": 42,         <a id="CO617-1"></a><i class="conum" data-value="1"></i>
            "relation": "eq"     <a id="CO617-2"></a><i class="conum" data-value="2"></i>
        },
        "hits": ...
    }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO617-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>42 documents match the query</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO617-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>and the count is accurate (<code class="literal">"eq"</code>)</p>
</td>
</tr>
</table>
</div>
<p>... indicates that the number of hits returned in the <code class="literal">total</code>
is accurate.</p>
<p>If the total number of hits that match the query is greater than the
value set in <code class="literal">track_total_hits</code>, the total hits in the response
will indicate that the returned value is a lower bound:</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
    "_shards": ...
    "hits" : {
        "max_score": 1.0,
        "total" : {
            "value": 100,         <a id="CO618-1"></a><i class="conum" data-value="1"></i>
            "relation": "gte"     <a id="CO618-2"></a><i class="conum" data-value="2"></i>
        },
        "hits": ...
    }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO618-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>There are at least 100 documents that match the query</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO618-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>This is a lower bound (<code class="literal">"gte"</code>).</p>
</td>
</tr>
</table>
</div>
<p>If you don’t need to track the total number of hits at all you can improve query
times by setting this option to <code class="literal">false</code>:</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">GET twitter/_search
{
    "track_total_hits": false,
     "query": {
        "match" : {
            "message" : "Elasticsearch"
        }
     }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/1979.console"></div>
<p>... returns:</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
    "_shards": ...
    "timed_out": false,
    "took": 10,
    "hits" : { <a id="CO619-1"></a><i class="conum" data-value="1"></i>
        "max_score": 1.0,
        "hits": ...
    }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO619-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>The total number of hits is unknown.</p>
</td>
</tr>
</table>
</div>
<p>Finally you can force an accurate count by setting <code class="literal">"track_total_hits"</code>
to <code class="literal">true</code> in the request.</p>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="search-search.html">« Search API</a>
</span>
<span class="next">
<a href="async-search.html">Async search »</a>
</span>
</div>
</div>

                  <!-- end body -->
                </div>
                <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                  <div id="rtpcontainer" style="display: block;">
                    <div class="mktg-promo">
                      <h3>Most Popular</h3>
                      <ul class="icons">
                        <li class="icon-elasticsearch-white"><a href="https://www.elastic.co/webinars/getting-started-elasticsearch?baymax=default&amp;elektra=docs&amp;storm=top-video">Get Started with Elasticsearch: Video</a></li>
                        <li class="icon-kibana-white"><a href="https://www.elastic.co/webinars/getting-started-kibana?baymax=default&amp;elektra=docs&amp;storm=top-video">Intro to Kibana: Video</a></li>
                        <li class="icon-logstash-white"><a href="https://www.elastic.co/webinars/introduction-elk-stack?baymax=default&amp;elektra=docs&amp;storm=top-video">ELK for Logs &amp; Metrics: Video</a></li>
                      </ul>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </section>

        </div>


<div id="elastic-footer"></div>
<script src="https://www.elastic.co/elastic-footer.js"></script>
<!-- Footer Section end-->

      </section>
    </div>

<script src="/guide/static/jquery.js"></script>
<script type="text/javascript" src="/guide/static/docs.js"></script>
<script type="text/javascript">
  window.initial_state = {}</script>
  </body>
</html>
